@bpmnkit/connectors 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 urbanisierung
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,145 @@
1
+ <div align="center">
2
+ <a href="https://bpmnkit.com"><img src="https://bpmnkit.com/favicon.svg" width="72" height="72" alt="BPMN Kit logo"></a>
3
+ <h1>@bpmnkit/connectors</h1>
4
+ <p>Camunda 8 out-of-the-box connector catalog and deterministic element-template application for @bpmnkit/core</p>
5
+
6
+ [![npm](https://img.shields.io/npm/v/@bpmnkit/connectors?style=flat-square&color=6244d7)](https://www.npmjs.com/package/@bpmnkit/connectors)
7
+ [![license](https://img.shields.io/npm/l/@bpmnkit/connectors?style=flat-square)](https://github.com/bpmnkit/monorepo/blob/main/LICENSE)
8
+ [![typescript](https://img.shields.io/badge/TypeScript-strict-6244d7?style=flat-square&logo=typescript&logoColor=white)](https://github.com/bpmnkit/monorepo)
9
+ [![ai-assisted](https://img.shields.io/badge/AI--assisted-claude-8b5cf6?style=flat-square)](https://github.com/bpmnkit/monorepo)
10
+ [![experimental](https://img.shields.io/badge/status-experimental-f59e0b?style=flat-square)](https://github.com/bpmnkit/monorepo)
11
+
12
+ [Website](https://bpmnkit.com) · [Documentation](https://bpmnkit.com/docs) · [GitHub](https://github.com/bpmnkit/monorepo) · [Changelog](https://github.com/bpmnkit/monorepo/blob/main/packages/connectors/CHANGELOG.md)
13
+ </div>
14
+
15
+ ---
16
+
17
+ ## Overview
18
+
19
+ `@bpmnkit/connectors` bundles the 116+ Camunda 8 out-of-the-box connector element templates (Slack, SendGrid, HTTP, Kafka, AWS, the agentic-AI family, and more) and applies them to `@bpmnkit/core` builder options deterministically — every binding kind (`zeebe:input`, `zeebe:output`, `zeebe:taskHeader`, `zeebe:taskDefinition`, `zeebe:property`, `zeebe:adHoc`), dropdown-gated conditions, required-field validation, and FEEL parse-checking on FEEL-tagged values.
20
+
21
+ ## Features
22
+
23
+ - **Full connector catalog** — search and inspect all bundled Camunda 8 OOTB templates
24
+ - **Complete binding resolution** — including `zeebe:property` and `zeebe:output`, which naive appliers drop
25
+ - **Required-field and FEEL validation** — problems are reported, never silently swallowed
26
+ - **Works with any template** — bundled catalog or a custom/generated `ElementTemplate`
27
+
28
+ ## Installation
29
+
30
+ ```sh
31
+ npm install @bpmnkit/connectors
32
+ ```
33
+
34
+ ## Quick Start
35
+
36
+ ```typescript
37
+ import { Bpmn } from "@bpmnkit/core"
38
+ import { applyConnectorTemplate, searchConnectors } from "@bpmnkit/connectors"
39
+
40
+ const [slack] = searchConnectors("slack")
41
+ const result = applyConnectorTemplate(slack.id, {
42
+ method: "chat.postMessage",
43
+ token: "{{secrets.SLACK_OAUTH_TOKEN}}",
44
+ "data.channel": "#ops",
45
+ "data.text": "=\"Order \" + orderId + \" failed validation\"",
46
+ })
47
+
48
+ if (result.problems.length > 0) throw new Error(result.problems[0].message)
49
+
50
+ const defs = Bpmn.createProcess("proc")
51
+ .startEvent("s")
52
+ .serviceTask("notify", result.serviceTask!)
53
+ .endEvent("e")
54
+ .build()
55
+ ```
56
+
57
+ ## Your project's own templates
58
+
59
+ Drop element templates in `.camunda/element-templates/` and they join the bundled catalogue —
60
+ no project configuration, no registration step. A template nearer the diagram wins over one at
61
+ the project root, which wins over the bundled version of the same id.
62
+
63
+ ```typescript
64
+ import { registerElementTemplates } from "@bpmnkit/connectors"
65
+ import { discoverElementTemplates } from "@bpmnkit/connectors/node"
66
+
67
+ const { templates, problems } = await discoverElementTemplates({
68
+ from: "processes/orders/order.bpmn",
69
+ root: process.cwd(),
70
+ })
71
+ registerElementTemplates(templates)
72
+ // `problems` names every template that was rejected, and why — nothing is dropped silently.
73
+ ```
74
+
75
+ The filesystem half lives behind `@bpmnkit/connectors/node`, so the main entry stays
76
+ importable in a browser: a studio or a viewer takes templates from its host instead.
77
+
78
+ Validate them in CI with `casen connector validate`.
79
+
80
+ ## API Reference
81
+
82
+ ```typescript
83
+ function listConnectors(): ConnectorSummary[]
84
+ function searchConnectors(query: string): ConnectorSummary[]
85
+ function getTemplate(id: string): ElementTemplate | undefined
86
+ function registerElementTemplates(templates: readonly ElementTemplate[]): void
87
+ function clearRegisteredTemplates(): void
88
+
89
+ function validateElementTemplate(value: unknown): TemplateValidation
90
+ function readTemplateDocument(value: unknown): TemplateDocumentResult
91
+
92
+ function applyConnectorTemplate(templateId: string, values?: Record<string, string>): ApplyResult
93
+ function applyElementTemplate(template: ElementTemplate, values?: Record<string, string>): ApplyResult
94
+
95
+ // @bpmnkit/connectors/node
96
+ function discoverElementTemplates(options: DiscoverOptions): Promise<DiscoveryResult>
97
+ function collectElementTemplates(options: { root: string; configFolder?: string }): Promise<DiscoveryResult>
98
+
99
+ interface ApplyResult {
100
+ serviceTask?: ServiceTaskOptions
101
+ adHocSubProcess?: Partial<AdHocSubProcessOptions>
102
+ startEvent?: Partial<StartEventOptions>
103
+ boundaryEvent?: Partial<BoundaryEventOptions>
104
+ intermediateEvent?: Partial<IntermediateCatchEventOptions>
105
+ problems: ApplyProblem[]
106
+ }
107
+ ```
108
+
109
+ ---
110
+
111
+ ## Related Packages
112
+
113
+ | Package | Description |
114
+ |---------|-------------|
115
+ | [`@bpmnkit/core`](https://www.npmjs.com/package/@bpmnkit/core) | BPMN/DMN/Form parser, builder, layout engine |
116
+ | [`@bpmnkit/canvas`](https://www.npmjs.com/package/@bpmnkit/canvas) | Zero-dependency SVG BPMN viewer |
117
+ | [`@bpmnkit/editor`](https://www.npmjs.com/package/@bpmnkit/editor) | Full-featured interactive BPMN editor |
118
+ | [`@bpmnkit/engine`](https://www.npmjs.com/package/@bpmnkit/engine) | Lightweight BPMN process execution engine |
119
+ | [`@bpmnkit/feel`](https://www.npmjs.com/package/@bpmnkit/feel) | FEEL expression language parser & evaluator |
120
+ | [`@bpmnkit/plugins`](https://www.npmjs.com/package/@bpmnkit/plugins) | 22 composable canvas plugins |
121
+ | [`@bpmnkit/api`](https://www.npmjs.com/package/@bpmnkit/api) | Camunda 8 REST API TypeScript client |
122
+ | [`@bpmnkit/ascii`](https://www.npmjs.com/package/@bpmnkit/ascii) | Render BPMN diagrams as Unicode ASCII art |
123
+ | [`@bpmnkit/docspack`](https://www.npmjs.com/package/@bpmnkit/docspack) | BPMN Kit docs as an offline docspack package for AI agents |
124
+ | [`@bpmnkit/ui`](https://www.npmjs.com/package/@bpmnkit/ui) | Shared design tokens and UI components |
125
+ | [`@bpmnkit/profiles`](https://www.npmjs.com/package/@bpmnkit/profiles) | Shared auth, profile storage, and client factories for CLI & proxy |
126
+ | [`@bpmnkit/operate`](https://www.npmjs.com/package/@bpmnkit/operate) | Monitoring & operations frontend for Camunda clusters |
127
+ | [`@bpmnkit/connector-gen`](https://www.npmjs.com/package/@bpmnkit/connector-gen) | Generate connector templates from OpenAPI specs |
128
+ | [`@bpmnkit/cli`](https://www.npmjs.com/package/@bpmnkit/cli) | Camunda 8 command-line interface (casen) |
129
+ | [`@bpmnkit/proxy`](https://www.npmjs.com/package/@bpmnkit/proxy) | Local AI bridge and Camunda API proxy server |
130
+ | [`@bpmnkit/patterns`](https://www.npmjs.com/package/@bpmnkit/patterns) | Domain process patterns for BPMNKit AIKit |
131
+ | [`@bpmnkit/reebe-wasm`](https://www.npmjs.com/package/@bpmnkit/reebe-wasm) | WebAssembly BPMN engine for browser simulation |
132
+ | [`@bpmnkit/worker-client`](https://www.npmjs.com/package/@bpmnkit/worker-client) | Thin Zeebe REST client for standalone workers |
133
+ | [`@bpmnkit/cli-sdk`](https://www.npmjs.com/package/@bpmnkit/cli-sdk) | Plugin authoring SDK for the casen CLI |
134
+ | [`@bpmnkit/create-casen-plugin`](https://www.npmjs.com/package/@bpmnkit/create-casen-plugin) | Scaffold a new casen CLI plugin in seconds |
135
+ | [`@bpmnkit/casen-report`](https://www.npmjs.com/package/@bpmnkit/casen-report) | HTML reports from Camunda 8 incident and SLA data |
136
+ | [`@bpmnkit/casen-worker-http`](https://www.npmjs.com/package/@bpmnkit/casen-worker-http) | Example HTTP worker plugin — completes jobs with live JSONPlaceholder API data |
137
+ | [`@bpmnkit/casen-worker-ai`](https://www.npmjs.com/package/@bpmnkit/casen-worker-ai) | AI task worker — classify, summarize, extract, and decide using Claude |
138
+
139
+ ## License
140
+
141
+ [MIT](https://github.com/bpmnkit/monorepo/blob/main/LICENSE) © BPMN Kit — made by [u11g](https://u11g.com)
142
+
143
+ <div align="center">
144
+ <a href="https://bpmnkit.com"><img src="https://bpmnkit.com/favicon.svg" width="32" height="32" alt="BPMN Kit"></a>
145
+ </div>
@@ -0,0 +1,67 @@
1
+ import type { AdHocSubProcessOptions, BoundaryEventOptions, IntermediateCatchEventOptions, ServiceTaskOptions, StartEventOptions } from "@bpmnkit/core";
2
+ import type { ElementTemplate } from "./template-types.js";
3
+ export interface ApplyProblem {
4
+ /** The property key this problem is about, if any. */
5
+ key?: string;
6
+ message: string;
7
+ /**
8
+ * What kind of problem this is — distinguishes a genuinely unmet required
9
+ * field ("missing-required") from an unrecognized values key
10
+ * ("unknown-key"), a FEEL syntax error ("invalid-feel"), or a template
11
+ * with no resolvable task type ("no-task-type"). Callers that specifically
12
+ * want "what's still required" (e.g. the deploy-lint connector check)
13
+ * must filter on `kind === "missing-required"` — an unknown key is not
14
+ * evidence that some other field is missing.
15
+ */
16
+ kind?: "missing-required" | "unknown-key" | "invalid-feel" | "no-task-type";
17
+ }
18
+ /**
19
+ * The result of applying a connector template — exactly one of `serviceTask`,
20
+ * `adHocSubProcess`, `startEvent`, `boundaryEvent`, or `intermediateEvent` is
21
+ * set, matching the template's direction. `problems` is always present and
22
+ * must be checked: a non-empty array means the template could not be fully
23
+ * applied (missing required value, unknown value key, or a FEEL parse error).
24
+ */
25
+ export interface ApplyResult {
26
+ serviceTask?: ServiceTaskOptions;
27
+ adHocSubProcess?: Partial<AdHocSubProcessOptions>;
28
+ startEvent?: Partial<StartEventOptions>;
29
+ boundaryEvent?: Partial<BoundaryEventOptions>;
30
+ intermediateEvent?: Partial<IntermediateCatchEventOptions>;
31
+ problems: ApplyProblem[];
32
+ }
33
+ /**
34
+ * The binding types `applyBinding` below writes.
35
+ *
36
+ * Declared beside the switch so the two are edited together: anything the
37
+ * switch gains belongs here, and `validateElementTemplate` warns about every
38
+ * binding that is valid but absent from this set — otherwise a template using
39
+ * one would apply silently and do nothing.
40
+ */
41
+ export declare const APPLIED_BINDING_TYPES: ReadonlySet<string>;
42
+ /**
43
+ * Applies a Camunda 8 out-of-the-box connector element template deterministically.
44
+ *
45
+ * Unlike a naive apply that only handles `zeebe:input`, this resolves every
46
+ * binding kind (`zeebe:input`, `zeebe:output`, `zeebe:taskHeader`,
47
+ * `zeebe:taskDefinition(:type)`, `zeebe:property`, `zeebe:adHoc`), respects
48
+ * dropdown-gated `condition`s, validates required fields, and parse-validates
49
+ * any value that looks like a FEEL expression (leading "=").
50
+ *
51
+ * `values` keys match `ConnectorSummary.requiredInputs[].key` /
52
+ * `optionalInputs[].key` from `listConnectors()`/`searchConnectors()`.
53
+ *
54
+ * Operates on any {@link ElementTemplate} object — not just the bundled OOTB
55
+ * catalog — so custom/generated templates (e.g. from `@bpmnkit/connector-gen`)
56
+ * work the same way. Use {@link applyConnectorTemplate} to apply by bundled
57
+ * template id instead.
58
+ */
59
+ export declare function applyElementTemplate(template: ElementTemplate, values?: Record<string, string>): ApplyResult;
60
+ /**
61
+ * Applies a bundled Camunda 8 out-of-the-box connector element template by
62
+ * id — see {@link applyElementTemplate} for the full binding-resolution
63
+ * behavior. Returns a single `problems` entry if `templateId` isn't in the
64
+ * bundled catalog (use `applyElementTemplate` directly for custom templates).
65
+ */
66
+ export declare function applyConnectorTemplate(templateId: string, values?: Record<string, string>): ApplyResult;
67
+ //# sourceMappingURL=apply.d.ts.map
package/dist/apply.js ADDED
@@ -0,0 +1,243 @@
1
+ import { parseExpression } from "@bpmnkit/feel";
2
+ import { getTemplate, propertyKey } from "./catalog.js";
3
+ function evalCondition(cond, values) {
4
+ if ("allMatch" in cond) {
5
+ return cond.allMatch.every((c) => evalCondition(c, values));
6
+ }
7
+ if ("equals" in cond)
8
+ return values[cond.property] === cond.equals;
9
+ if ("oneOf" in cond)
10
+ return cond.oneOf.includes(values[cond.property] ?? "");
11
+ if ("isActive" in cond)
12
+ return Boolean(values[cond.property]) === cond.isActive;
13
+ return true;
14
+ }
15
+ function defaultValueOf(prop) {
16
+ if (prop.value === undefined)
17
+ return undefined;
18
+ return String(prop.value);
19
+ }
20
+ /** Resolves every property to its effective string value: user override, else template default. */
21
+ function resolveValues(template, values) {
22
+ const resolved = {};
23
+ for (const prop of template.properties) {
24
+ const key = propertyKey(prop);
25
+ if (!key)
26
+ continue;
27
+ const value = values[key] ?? defaultValueOf(prop);
28
+ if (value !== undefined)
29
+ resolved[key] = value;
30
+ }
31
+ return resolved;
32
+ }
33
+ /**
34
+ * The binding types `applyBinding` below writes.
35
+ *
36
+ * Declared beside the switch so the two are edited together: anything the
37
+ * switch gains belongs here, and `validateElementTemplate` warns about every
38
+ * binding that is valid but absent from this set — otherwise a template using
39
+ * one would apply silently and do nothing.
40
+ */
41
+ export const APPLIED_BINDING_TYPES = new Set([
42
+ "zeebe:input",
43
+ "zeebe:output",
44
+ "zeebe:taskHeader",
45
+ "zeebe:taskDefinition",
46
+ "zeebe:taskDefinition:type",
47
+ "zeebe:property",
48
+ "zeebe:adHoc",
49
+ "property",
50
+ ]);
51
+ function applyBinding(binding, value, accum) {
52
+ switch (binding.type) {
53
+ case "zeebe:input":
54
+ accum.inputs.push({ source: value, target: binding.name });
55
+ return;
56
+ case "zeebe:output":
57
+ // `binding.source` is the template's fixed FEEL read expression (e.g. "=response");
58
+ // `value` is the user-chosen process-variable name to write it to.
59
+ accum.outputs.push({ source: binding.source, target: value });
60
+ return;
61
+ case "zeebe:taskHeader":
62
+ accum.taskHeaders[binding.key] = value;
63
+ return;
64
+ case "zeebe:taskDefinition":
65
+ if (binding.property === "type")
66
+ accum.taskType = value;
67
+ else
68
+ accum.retries = value;
69
+ return;
70
+ case "zeebe:taskDefinition:type":
71
+ accum.taskType = value;
72
+ return;
73
+ case "zeebe:property":
74
+ accum.zeebeProperties.push({ name: binding.name, value });
75
+ return;
76
+ case "zeebe:adHoc":
77
+ accum.adHoc[binding.property] = value;
78
+ return;
79
+ case "property":
80
+ // "name" binds to the element's display name — handled by the caller, not here.
81
+ return;
82
+ default:
83
+ return;
84
+ }
85
+ }
86
+ function directionOf(template) {
87
+ return template.elementType?.value ?? template.appliesTo[0] ?? "";
88
+ }
89
+ /**
90
+ * Applies a Camunda 8 out-of-the-box connector element template deterministically.
91
+ *
92
+ * Unlike a naive apply that only handles `zeebe:input`, this resolves every
93
+ * binding kind (`zeebe:input`, `zeebe:output`, `zeebe:taskHeader`,
94
+ * `zeebe:taskDefinition(:type)`, `zeebe:property`, `zeebe:adHoc`), respects
95
+ * dropdown-gated `condition`s, validates required fields, and parse-validates
96
+ * any value that looks like a FEEL expression (leading "=").
97
+ *
98
+ * `values` keys match `ConnectorSummary.requiredInputs[].key` /
99
+ * `optionalInputs[].key` from `listConnectors()`/`searchConnectors()`.
100
+ *
101
+ * Operates on any {@link ElementTemplate} object — not just the bundled OOTB
102
+ * catalog — so custom/generated templates (e.g. from `@bpmnkit/connector-gen`)
103
+ * work the same way. Use {@link applyConnectorTemplate} to apply by bundled
104
+ * template id instead.
105
+ */
106
+ export function applyElementTemplate(template, values = {}) {
107
+ const resolved = resolveValues(template, values);
108
+ const problems = [];
109
+ const knownKeys = new Set(template.properties.map(propertyKey).filter(Boolean));
110
+ for (const key of Object.keys(values)) {
111
+ if (key !== "name" && !knownKeys.has(key)) {
112
+ problems.push({
113
+ key,
114
+ kind: "unknown-key",
115
+ message: `Unknown value key "${key}" for template "${template.id}"`,
116
+ });
117
+ }
118
+ }
119
+ const accum = {
120
+ inputs: [],
121
+ outputs: [],
122
+ taskHeaders: {},
123
+ zeebeProperties: [],
124
+ adHoc: {},
125
+ };
126
+ for (const prop of template.properties) {
127
+ const key = propertyKey(prop);
128
+ if (prop.condition && !evalCondition(prop.condition, resolved))
129
+ continue;
130
+ const value = resolved[key];
131
+ if (value === undefined || value === "") {
132
+ if (prop.type !== "Hidden" && prop.constraints?.notEmpty) {
133
+ problems.push({
134
+ key,
135
+ kind: "missing-required",
136
+ message: `Missing required value for "${prop.label ?? key}" (${key})`,
137
+ });
138
+ }
139
+ continue;
140
+ }
141
+ if ((prop.feel === "required" || prop.feel === "optional") && value.startsWith("=")) {
142
+ const { errors } = parseExpression(value.slice(1));
143
+ for (const err of errors) {
144
+ problems.push({
145
+ key,
146
+ kind: "invalid-feel",
147
+ message: `Invalid FEEL expression for "${key}": ${err.message}`,
148
+ });
149
+ }
150
+ }
151
+ applyBinding(prop.binding, value, accum);
152
+ }
153
+ const modelerTemplate = template.id;
154
+ const modelerTemplateVersion = template.version !== undefined ? String(template.version) : undefined;
155
+ const modelerTemplateIcon = template.icon?.contents;
156
+ const name = values.name ?? template.name;
157
+ const direction = directionOf(template);
158
+ if (direction === "bpmn:AdHocSubProcess") {
159
+ return {
160
+ adHocSubProcess: {
161
+ name,
162
+ taskDefinition: accum.taskType
163
+ ? { type: accum.taskType, retries: accum.retries }
164
+ : undefined,
165
+ ioMapping: accum.inputs.length || accum.outputs.length
166
+ ? { inputs: accum.inputs, outputs: accum.outputs }
167
+ : undefined,
168
+ taskHeaders: Object.keys(accum.taskHeaders).length > 0 ? accum.taskHeaders : undefined,
169
+ zeebeProperties: accum.zeebeProperties.length > 0 ? accum.zeebeProperties : undefined,
170
+ outputCollection: accum.adHoc.outputCollection,
171
+ outputElement: accum.adHoc.outputElement,
172
+ activeElementsCollection: accum.adHoc.activeElementsCollection,
173
+ modelerTemplate,
174
+ modelerTemplateVersion,
175
+ modelerTemplateIcon,
176
+ },
177
+ problems,
178
+ };
179
+ }
180
+ if (direction === "bpmn:StartEvent" ||
181
+ direction === "bpmn:BoundaryEvent" ||
182
+ direction === "bpmn:IntermediateCatchEvent" ||
183
+ direction === "bpmn:ReceiveTask") {
184
+ if (accum.inputs.length > 0 ||
185
+ accum.outputs.length > 0 ||
186
+ Object.keys(accum.taskHeaders).length > 0) {
187
+ problems.push({
188
+ message: "Template uses zeebe:input/output/taskHeader bindings on an event-attached element; " +
189
+ "applyConnectorTemplate() only maps zeebe:property for start/boundary/intermediate events. " +
190
+ "Apply the remaining bindings manually.",
191
+ });
192
+ }
193
+ const partial = {
194
+ name,
195
+ zeebeProperties: accum.zeebeProperties.length > 0 ? accum.zeebeProperties : undefined,
196
+ modelerTemplate,
197
+ modelerTemplateVersion,
198
+ modelerTemplateIcon,
199
+ };
200
+ if (direction === "bpmn:StartEvent")
201
+ return { startEvent: partial, problems };
202
+ if (direction === "bpmn:BoundaryEvent")
203
+ return { boundaryEvent: partial, problems };
204
+ return { intermediateEvent: partial, problems };
205
+ }
206
+ // Default: outbound service task (bpmn:ServiceTask, bpmn:SendTask, bpmn:EndEvent, bpmn:Task, ...)
207
+ if (!accum.taskType) {
208
+ problems.push({
209
+ kind: "no-task-type",
210
+ message: `Template "${template.id}" produced no zeebe:taskDefinition type`,
211
+ });
212
+ }
213
+ return {
214
+ serviceTask: {
215
+ name,
216
+ taskType: accum.taskType ?? "",
217
+ retries: accum.retries,
218
+ ioMapping: accum.inputs.length || accum.outputs.length
219
+ ? { inputs: accum.inputs, outputs: accum.outputs }
220
+ : undefined,
221
+ taskHeaders: Object.keys(accum.taskHeaders).length > 0 ? accum.taskHeaders : undefined,
222
+ zeebeProperties: accum.zeebeProperties.length > 0 ? accum.zeebeProperties : undefined,
223
+ modelerTemplate,
224
+ modelerTemplateVersion,
225
+ modelerTemplateIcon,
226
+ },
227
+ problems,
228
+ };
229
+ }
230
+ /**
231
+ * Applies a bundled Camunda 8 out-of-the-box connector element template by
232
+ * id — see {@link applyElementTemplate} for the full binding-resolution
233
+ * behavior. Returns a single `problems` entry if `templateId` isn't in the
234
+ * bundled catalog (use `applyElementTemplate` directly for custom templates).
235
+ */
236
+ export function applyConnectorTemplate(templateId, values = {}) {
237
+ const template = getTemplate(templateId);
238
+ if (!template) {
239
+ return { problems: [{ message: `Unknown connector template "${templateId}"` }] };
240
+ }
241
+ return applyElementTemplate(template, values);
242
+ }
243
+ //# sourceMappingURL=apply.js.map
@@ -0,0 +1,76 @@
1
+ import type { ElementTemplate, TemplateCondition, TemplateProperty } from "./template-types.js";
2
+ /** Where in the process a connector template attaches. */
3
+ export type ConnectorDirection = "outbound" | "inbound-start" | "inbound-intermediate" | "inbound-boundary"
4
+ /** The AI Agent Sub-process connector — an ad-hoc sub-process, not a single task. */
5
+ | "agentic";
6
+ /** One user-configurable (non-Hidden) property on a connector template. */
7
+ export interface ConnectorInputSpec {
8
+ /** Lookup key — matches the keys `applyConnectorTemplate()` expects in its `values` argument. */
9
+ key: string;
10
+ label: string;
11
+ description?: string;
12
+ /** True for fields whose label/key suggest a credential (API key, token, password, secret). */
13
+ isSecret: boolean;
14
+ /** True if the field's value is interpreted as FEEL (a leading "=" makes it an expression). */
15
+ isFeel: boolean;
16
+ default?: string | number | boolean;
17
+ choices?: Array<{
18
+ name: string;
19
+ value: string;
20
+ }>;
21
+ /** This field only applies (and is only required) when this condition holds against other values. */
22
+ condition?: TemplateCondition;
23
+ }
24
+ /** A connector template reduced to what a skill or LLM needs to select and configure it. */
25
+ export interface ConnectorSummary {
26
+ id: string;
27
+ name: string;
28
+ description?: string;
29
+ /** Zeebe job type this template sets, e.g. "io.camunda:slack:1". Absent for some inbound templates. */
30
+ taskType?: string;
31
+ appliesTo: string[];
32
+ direction: ConnectorDirection;
33
+ keywords: string[];
34
+ requiredInputs: ConnectorInputSpec[];
35
+ optionalInputs: ConnectorInputSpec[];
36
+ }
37
+ /** Same key-derivation logic used at apply time — kept in sync with `apply.ts`. */
38
+ export declare function propertyKey(prop: TemplateProperty): string;
39
+ /**
40
+ * What a template will do, without applying it.
41
+ *
42
+ * The catalogue computes this for every listing already; it is exported because
43
+ * anything offering a template to a person needs to be able to say what it
44
+ * binds and what it will ask for — a picker that applies on the first click is
45
+ * asking someone to choose blind.
46
+ *
47
+ * @param template - The template to describe.
48
+ */
49
+ export declare function summarizeTemplate(template: ElementTemplate): ConnectorSummary;
50
+ /**
51
+ * Adds templates to the catalogue, replacing any bundled template with the same
52
+ * id.
53
+ *
54
+ * The workspace wins deliberately: a project that ships its own version of a
55
+ * connector means it, and the bundle is the fallback. Registering the same id
56
+ * twice keeps the later one, so a nearer directory can override a further one.
57
+ *
58
+ * @param templates - Validated templates. Nothing is checked here; run
59
+ * `validateElementTemplate` (or `readTemplateDocument`) at the boundary where
60
+ * the JSON was read, so a bad file is reported against its own path.
61
+ */
62
+ export declare function registerElementTemplates(templates: readonly ElementTemplate[]): void;
63
+ /** Drops every registered template, leaving only the bundled catalogue. */
64
+ export declare function clearRegisteredTemplates(): void;
65
+ /** Every connector template — bundled and registered — as a compact summary. */
66
+ export declare function listConnectors(): ConnectorSummary[];
67
+ /** The full element template for a given template id, registered or bundled. */
68
+ export declare function getTemplate(id: string): ElementTemplate | undefined;
69
+ /**
70
+ * Keyword-scored search over the bundled connector catalog — mirrors
71
+ * `@bpmnkit/patterns`' `findPattern()` matching style. Matches against the
72
+ * template name are weighted highest, then keyword-list matches, then a
73
+ * general substring match; ties prefer outbound connectors.
74
+ */
75
+ export declare function searchConnectors(query: string): ConnectorSummary[];
76
+ //# sourceMappingURL=catalog.d.ts.map