@camunda8/cli 2.8.0-alpha.8 → 3.0.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/EXAMPLES.md +22 -5
- package/PLUGIN-HELP.md +26 -0
- package/README.md +62 -4
- package/dist/command-dispatch.d.ts.map +1 -1
- package/dist/command-dispatch.js +2 -1
- package/dist/command-dispatch.js.map +1 -1
- package/dist/command-registry.d.ts +36 -0
- package/dist/command-registry.d.ts.map +1 -1
- package/dist/command-registry.js +40 -1
- package/dist/command-registry.js.map +1 -1
- package/dist/commands/plugins.d.ts +21 -0
- package/dist/commands/plugins.d.ts.map +1 -1
- package/dist/commands/plugins.js +74 -1
- package/dist/commands/plugins.js.map +1 -1
- package/dist/commands/resource-extensions.d.ts +12 -0
- package/dist/commands/resource-extensions.d.ts.map +1 -1
- package/dist/commands/resource-extensions.js +13 -1
- package/dist/commands/resource-extensions.js.map +1 -1
- package/dist/commands/run.d.ts.map +1 -1
- package/dist/commands/run.js +5 -3
- package/dist/commands/run.js.map +1 -1
- package/dist/commands/watch.d.ts.map +1 -1
- package/dist/commands/watch.js +21 -12
- package/dist/commands/watch.js.map +1 -1
- package/dist/completion.d.ts.map +1 -1
- package/dist/completion.js +140 -13
- package/dist/completion.js.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +19 -1
- package/dist/config.js.map +1 -1
- package/dist/default-plugins/bpmn/README.md +69 -0
- package/dist/default-plugins/bpmn/c8ctl-plugin.js +125 -0
- package/dist/default-plugins/bpmn/c8ctl-plugin.js.map +1 -0
- package/dist/default-plugins/bpmn/lint.js +259 -0
- package/dist/default-plugins/bpmn/lint.js.map +1 -0
- package/dist/default-plugins/bpmn/package.json +8 -0
- package/dist/default-plugins/cluster/package.json +1 -1
- package/dist/default-plugins/element-template/AGENTS.md +65 -0
- package/dist/default-plugins/element-template/README.md +331 -0
- package/dist/default-plugins/element-template/c8ctl-plugin.js +247 -0
- package/dist/default-plugins/element-template/c8ctl-plugin.js.map +1 -0
- package/dist/default-plugins/element-template/commands/apply.js +298 -0
- package/dist/default-plugins/element-template/commands/apply.js.map +1 -0
- package/dist/default-plugins/element-template/commands/get-properties.js +344 -0
- package/dist/default-plugins/element-template/commands/get-properties.js.map +1 -0
- package/dist/default-plugins/element-template/commands/get.js +107 -0
- package/dist/default-plugins/element-template/commands/get.js.map +1 -0
- package/dist/default-plugins/element-template/commands/info.js +189 -0
- package/dist/default-plugins/element-template/commands/info.js.map +1 -0
- package/dist/default-plugins/element-template/commands/search.js +101 -0
- package/dist/default-plugins/element-template/commands/search.js.map +1 -0
- package/dist/default-plugins/element-template/commands/sync.js +36 -0
- package/dist/default-plugins/element-template/commands/sync.js.map +1 -0
- package/dist/default-plugins/element-template/docs/design.md +145 -0
- package/dist/default-plugins/element-template/helpers.js +404 -0
- package/dist/default-plugins/element-template/helpers.js.map +1 -0
- package/dist/default-plugins/element-template/marketplace.js +396 -0
- package/dist/default-plugins/element-template/marketplace.js.map +1 -0
- package/dist/default-plugins/element-template/package.json +8 -0
- package/dist/default-plugins/element-template/template-ref.js +232 -0
- package/dist/default-plugins/element-template/template-ref.js.map +1 -0
- package/dist/default-plugins/element-template/vendor-src/bundle-entry.js +44 -0
- package/dist/default-plugins/feel/README.md +163 -0
- package/dist/default-plugins/feel/c8ctl-plugin.js +616 -0
- package/dist/default-plugins/feel/c8ctl-plugin.js.map +1 -0
- package/dist/default-plugins/feel/package.json +8 -0
- package/dist/deployments.d.ts +1 -0
- package/dist/deployments.d.ts.map +1 -1
- package/dist/deployments.js +89 -20
- package/dist/deployments.js.map +1 -1
- package/dist/help.d.ts.map +1 -1
- package/dist/help.js +156 -5
- package/dist/help.js.map +1 -1
- package/dist/ignore.d.ts +16 -1
- package/dist/ignore.d.ts.map +1 -1
- package/dist/ignore.js +55 -3
- package/dist/ignore.js.map +1 -1
- package/dist/index.d.ts +23 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +310 -25
- package/dist/index.js.map +1 -1
- package/dist/plugin-loader.d.ts +168 -7
- package/dist/plugin-loader.d.ts.map +1 -1
- package/dist/plugin-loader.js +284 -21
- package/dist/plugin-loader.js.map +1 -1
- package/dist/runtime.d.ts +10 -0
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +6 -0
- package/dist/runtime.js.map +1 -1
- package/dist/vendor/bpmn-element-templates.cjs +59639 -0
- package/package.json +20 -7
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* c8ctl-plugin-bpmn
|
|
3
|
+
*
|
|
4
|
+
* Lint BPMN diagrams against recommended and Camunda rules.
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* c8ctl bpmn lint <file.bpmn>
|
|
8
|
+
* cat file.bpmn | c8ctl bpmn lint
|
|
9
|
+
*/
|
|
10
|
+
import { lintSubcommand } from "./lint.js";
|
|
11
|
+
if (!globalThis.c8ctl)
|
|
12
|
+
throw new Error("c8ctl runtime not initialised");
|
|
13
|
+
const c8ctl = globalThis.c8ctl;
|
|
14
|
+
// Ambient module declarations for the untyped bpmn-io ecosystem live in
|
|
15
|
+
// ./bpmn-io.d.ts (TS does not allow `declare module` inside module files
|
|
16
|
+
// for modules that resolve to actual files).
|
|
17
|
+
/**
|
|
18
|
+
* Reinject flags pre-parsed by the host (#366/#367) back into the args
|
|
19
|
+
* array as `--name value` / `--name` tokens, so the plugin's hand-rolled
|
|
20
|
+
* `parseArgs` still sees them.
|
|
21
|
+
*/
|
|
22
|
+
function injectFlagsIntoArgs(args, flags) {
|
|
23
|
+
const out = [...args];
|
|
24
|
+
if (!flags) {
|
|
25
|
+
return out;
|
|
26
|
+
}
|
|
27
|
+
for (const [name, value] of Object.entries(flags)) {
|
|
28
|
+
if (value === undefined || value === null) {
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
if (typeof value === "boolean") {
|
|
32
|
+
if (value) {
|
|
33
|
+
out.push(`--${name}`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
else if (Array.isArray(value)) {
|
|
37
|
+
for (const item of value) {
|
|
38
|
+
if (item !== undefined && item !== null) {
|
|
39
|
+
out.push(`--${name}`, String(item));
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
out.push(`--${name}`, String(value));
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return out;
|
|
48
|
+
}
|
|
49
|
+
async function bpmnHandler(args, flags) {
|
|
50
|
+
const reinjected = injectFlagsIntoArgs(args ?? [], flags);
|
|
51
|
+
const subcommand = reinjected[0];
|
|
52
|
+
const subArgs = reinjected.slice(1);
|
|
53
|
+
const validSubcommands = metadata.commands.bpmn.subcommands.map((s) => s.name);
|
|
54
|
+
if (!subcommand || !validSubcommands.includes(subcommand)) {
|
|
55
|
+
const logger = c8ctl.getLogger();
|
|
56
|
+
const lead = subcommand
|
|
57
|
+
? `Unknown subcommand '${subcommand}'.`
|
|
58
|
+
: "c8ctl bpmn requires a subcommand.";
|
|
59
|
+
logger.info(`${lead} Available: ${validSubcommands.join(", ")}`);
|
|
60
|
+
logger.info("Run 'c8ctl bpmn --help' for full usage.");
|
|
61
|
+
process.exitCode = 1;
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
try {
|
|
65
|
+
if (subcommand === "lint")
|
|
66
|
+
await lintSubcommand(subArgs);
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
70
|
+
const logger = c8ctl.getLogger();
|
|
71
|
+
logger.error(`Failed to bpmn ${subcommand}: ${message}`);
|
|
72
|
+
process.exitCode = 1;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
// ---------------------------------------------------------------------------
|
|
76
|
+
// Plugin API
|
|
77
|
+
// ---------------------------------------------------------------------------
|
|
78
|
+
export const metadata = {
|
|
79
|
+
name: "bpmn",
|
|
80
|
+
description: "Lint BPMN diagrams",
|
|
81
|
+
commands: {
|
|
82
|
+
bpmn: {
|
|
83
|
+
description: "BPMN tooling — lint diagrams (supports stdin piping)",
|
|
84
|
+
helpDescription: "Lint BPMN diagrams. Supports file paths and stdin piping.\n\n" +
|
|
85
|
+
"Rule configuration: a .bpmnlintrc in the working directory takes precedence. " +
|
|
86
|
+
"Otherwise the linter extends bpmnlint:recommended plus the matching " +
|
|
87
|
+
"camunda-compat/camunda-cloud-<version> ruleset, auto-detected from " +
|
|
88
|
+
'modeler:executionPlatform="Camunda Cloud" and ' +
|
|
89
|
+
"modeler:executionPlatformVersion in the BPMN file.",
|
|
90
|
+
subcommands: [
|
|
91
|
+
{
|
|
92
|
+
name: "lint",
|
|
93
|
+
description: "Lint a BPMN diagram against recommended and Camunda rules",
|
|
94
|
+
},
|
|
95
|
+
],
|
|
96
|
+
examples: [
|
|
97
|
+
{
|
|
98
|
+
command: "c8ctl bpmn lint process.bpmn",
|
|
99
|
+
description: "Lint a BPMN file with Camunda rules",
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
command: "cat process.bpmn | c8ctl bpmn lint",
|
|
103
|
+
description: "Lint from stdin",
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
command: "c8ctl bpmn lint --quiet process.bpmn",
|
|
107
|
+
description: "Suppress the success line in scripts",
|
|
108
|
+
},
|
|
109
|
+
],
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
};
|
|
113
|
+
export const commands = {
|
|
114
|
+
bpmn: {
|
|
115
|
+
flags: {
|
|
116
|
+
quiet: {
|
|
117
|
+
type: "boolean",
|
|
118
|
+
short: "q",
|
|
119
|
+
description: 'Suppress the "No issues found." line on a clean lint',
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
handler: bpmnHandler,
|
|
123
|
+
},
|
|
124
|
+
};
|
|
125
|
+
//# sourceMappingURL=c8ctl-plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"c8ctl-plugin.js","sourceRoot":"","sources":["../../../default-plugins/bpmn/c8ctl-plugin.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BPMN lint internals — bpmnlint driver, config resolution, and the
|
|
3
|
+
* collect-then-render split that powers `c8ctl bpmn lint`. The plugin
|
|
4
|
+
* file (./c8ctl-plugin.ts) only handles host glue and CLI dispatch.
|
|
5
|
+
*/
|
|
6
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
7
|
+
import { createRequire } from "node:module";
|
|
8
|
+
import { resolve as resolvePath } from "node:path";
|
|
9
|
+
import { styleText } from "node:util";
|
|
10
|
+
if (!globalThis.c8ctl)
|
|
11
|
+
throw new Error("c8ctl runtime not initialised");
|
|
12
|
+
const c8ctl = globalThis.c8ctl;
|
|
13
|
+
const require = createRequire(import.meta.url);
|
|
14
|
+
function isRecord(value) {
|
|
15
|
+
return value != null && typeof value === "object" && !Array.isArray(value);
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Read BPMN XML from a file path or stdin. Returns null if no input is available.
|
|
19
|
+
*
|
|
20
|
+
* Stdin is consumed via async iteration so a slow upstream writer (e.g.
|
|
21
|
+
* `apply | lint` in a pipeline, or any producer that hasn't flushed yet)
|
|
22
|
+
* is awaited until 'end'. Do not use `readFileSync(0)` here — when stdin
|
|
23
|
+
* is a pipe with no buffered data yet, it throws EAGAIN, which gets
|
|
24
|
+
* swallowed and surfaces as "no input".
|
|
25
|
+
*/
|
|
26
|
+
async function readBpmnInput(filePath) {
|
|
27
|
+
if (filePath) {
|
|
28
|
+
const resolved = resolvePath(filePath);
|
|
29
|
+
if (!existsSync(resolved)) {
|
|
30
|
+
throw new Error(`File not found: ${filePath}`);
|
|
31
|
+
}
|
|
32
|
+
return { xml: readFileSync(resolved, "utf-8"), source: resolved };
|
|
33
|
+
}
|
|
34
|
+
if (!process.stdin.isTTY) {
|
|
35
|
+
process.stdin.setEncoding("utf-8");
|
|
36
|
+
let xml = "";
|
|
37
|
+
for await (const chunk of process.stdin) {
|
|
38
|
+
xml += chunk;
|
|
39
|
+
}
|
|
40
|
+
if (!xml.trim())
|
|
41
|
+
return null;
|
|
42
|
+
return { xml, source: "stdin" };
|
|
43
|
+
}
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
function detectCamundaCloudVersion(rootElement) {
|
|
47
|
+
const attrs = rootElement.$attrs ?? {};
|
|
48
|
+
const platform = attrs["modeler:executionPlatform"];
|
|
49
|
+
const version = attrs["modeler:executionPlatformVersion"];
|
|
50
|
+
if (platform !== "Camunda Cloud" || !version) {
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
const match = version.match(/^(\d+\.\d+)/);
|
|
54
|
+
return match ? match[1] : null;
|
|
55
|
+
}
|
|
56
|
+
function resolveCamundaCompatConfig(version) {
|
|
57
|
+
const plugin = require("bpmnlint-plugin-camunda-compat");
|
|
58
|
+
const configs = plugin.configs;
|
|
59
|
+
const configName = `camunda-cloud-${version.replace(".", "-")}`;
|
|
60
|
+
if (configName in configs) {
|
|
61
|
+
return `plugin:camunda-compat/${configName}`;
|
|
62
|
+
}
|
|
63
|
+
const cloudConfigs = Object.keys(configs)
|
|
64
|
+
.filter((k) => k.startsWith("camunda-cloud-"))
|
|
65
|
+
.sort((a, b) => {
|
|
66
|
+
const parse = (s) => s.replace("camunda-cloud-", "").split("-").map(Number);
|
|
67
|
+
const va = parse(a);
|
|
68
|
+
const vb = parse(b);
|
|
69
|
+
for (let i = 0; i < Math.max(va.length, vb.length); i++) {
|
|
70
|
+
const diff = (va[i] || 0) - (vb[i] || 0);
|
|
71
|
+
if (diff !== 0) {
|
|
72
|
+
return diff;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return 0;
|
|
76
|
+
});
|
|
77
|
+
if (cloudConfigs.length > 0) {
|
|
78
|
+
return `plugin:camunda-compat/${cloudConfigs[cloudConfigs.length - 1]}`;
|
|
79
|
+
}
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
function buildLintConfig(rootElement) {
|
|
83
|
+
const rcPath = resolvePath(".bpmnlintrc");
|
|
84
|
+
if (existsSync(rcPath)) {
|
|
85
|
+
const parsed = JSON.parse(readFileSync(rcPath, "utf-8"));
|
|
86
|
+
if (!isRecord(parsed)) {
|
|
87
|
+
throw new Error(".bpmnlintrc must contain a JSON object");
|
|
88
|
+
}
|
|
89
|
+
return parsed;
|
|
90
|
+
}
|
|
91
|
+
const config = { extends: ["bpmnlint:recommended"] };
|
|
92
|
+
const version = detectCamundaCloudVersion(rootElement);
|
|
93
|
+
if (version) {
|
|
94
|
+
const compatConfig = resolveCamundaCompatConfig(version);
|
|
95
|
+
if (compatConfig)
|
|
96
|
+
config.extends.push(compatConfig);
|
|
97
|
+
}
|
|
98
|
+
return config;
|
|
99
|
+
}
|
|
100
|
+
function formatElementRef(report, pathStringify) {
|
|
101
|
+
const id = report.id ?? "";
|
|
102
|
+
if (report.path) {
|
|
103
|
+
return `${id}#${pathStringify(report.path)}`;
|
|
104
|
+
}
|
|
105
|
+
return id;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Flatten bpmnlint's `{ ruleName: [report, ...] }` shape into a typed
|
|
109
|
+
* issue list plus the parallel `rows` list that the text renderer
|
|
110
|
+
* formats into a column-aligned table.
|
|
111
|
+
*/
|
|
112
|
+
function collectLintResult(results) {
|
|
113
|
+
let errorCount = 0;
|
|
114
|
+
let warningCount = 0;
|
|
115
|
+
const issues = [];
|
|
116
|
+
const rows = [];
|
|
117
|
+
const { pathStringify } = require("@bpmn-io/moddle-utils");
|
|
118
|
+
for (const [ruleName, reports] of Object.entries(results)) {
|
|
119
|
+
for (const report of reports) {
|
|
120
|
+
const elementRef = formatElementRef(report, pathStringify);
|
|
121
|
+
const displayName = report.name ?? ruleName;
|
|
122
|
+
const severity = report.category === "error" ? "error" : "warning";
|
|
123
|
+
rows.push({
|
|
124
|
+
elementRef,
|
|
125
|
+
severity,
|
|
126
|
+
message: report.message,
|
|
127
|
+
displayName,
|
|
128
|
+
category: report.category,
|
|
129
|
+
});
|
|
130
|
+
const issue = {
|
|
131
|
+
rule: report.name ?? ruleName,
|
|
132
|
+
elementId: report.id || null,
|
|
133
|
+
message: report.message,
|
|
134
|
+
category: report.category === "warn" ? "warning" : report.category,
|
|
135
|
+
};
|
|
136
|
+
if (report.path) {
|
|
137
|
+
issue.path = report.path;
|
|
138
|
+
}
|
|
139
|
+
issues.push(issue);
|
|
140
|
+
if (report.category === "error")
|
|
141
|
+
errorCount++;
|
|
142
|
+
else
|
|
143
|
+
warningCount++;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
return { rows, issues, errorCount, warningCount };
|
|
147
|
+
}
|
|
148
|
+
function renderLintJson(logger, file, result) {
|
|
149
|
+
logger.json({
|
|
150
|
+
file,
|
|
151
|
+
issues: result.issues,
|
|
152
|
+
errorCount: result.errorCount,
|
|
153
|
+
warningCount: result.warningCount,
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
function renderLintText(logger, source, result, options) {
|
|
157
|
+
const { rows, errorCount, warningCount } = result;
|
|
158
|
+
const problemCount = errorCount + warningCount;
|
|
159
|
+
if (problemCount === 0) {
|
|
160
|
+
if (!options.quiet) {
|
|
161
|
+
// Mirror the bold red ✖ summary used for problems with a bold green
|
|
162
|
+
// ✓ on success — gives the user an unambiguous "lint ran cleanly"
|
|
163
|
+
// signal instead of trailing silence.
|
|
164
|
+
logger.output(styleText(["bold", "green"], "✓ No issues found."));
|
|
165
|
+
}
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
// Compute column widths from the uncolored values so padding lines up
|
|
169
|
+
// regardless of terminal color support.
|
|
170
|
+
const widths = rows.reduce((acc, r) => ({
|
|
171
|
+
elementRef: Math.max(acc.elementRef, r.elementRef.length),
|
|
172
|
+
severity: Math.max(acc.severity, r.severity.length),
|
|
173
|
+
message: Math.max(acc.message, r.message.length),
|
|
174
|
+
}), { elementRef: 0, severity: 0, message: 0 });
|
|
175
|
+
const padEnd = (s, n) => s + " ".repeat(Math.max(0, n - s.length));
|
|
176
|
+
const sourceLabel = source === "stdin" ? "stdin" : resolvePath(source);
|
|
177
|
+
logger.output("");
|
|
178
|
+
logger.output(styleText("underline", sourceLabel));
|
|
179
|
+
for (const r of rows) {
|
|
180
|
+
const severityColor = r.category === "error" ? "red" : "yellow";
|
|
181
|
+
const severityCell = styleText(severityColor, padEnd(r.severity, widths.severity));
|
|
182
|
+
logger.output([
|
|
183
|
+
" ",
|
|
184
|
+
padEnd(r.elementRef, widths.elementRef),
|
|
185
|
+
severityCell,
|
|
186
|
+
padEnd(r.message, widths.message),
|
|
187
|
+
r.displayName,
|
|
188
|
+
].join(" "));
|
|
189
|
+
}
|
|
190
|
+
const pluralize = (word, count) => count === 1 ? word : `${word}s`;
|
|
191
|
+
const summary = `✖ ${problemCount} ${pluralize("problem", problemCount)} ` +
|
|
192
|
+
`(${errorCount} ${pluralize("error", errorCount)}, ` +
|
|
193
|
+
`${warningCount} ${pluralize("warning", warningCount)})`;
|
|
194
|
+
const summaryColor = errorCount > 0 ? ["bold", "red"] : ["bold", "yellow"];
|
|
195
|
+
logger.output("");
|
|
196
|
+
logger.output(styleText(summaryColor, summary));
|
|
197
|
+
}
|
|
198
|
+
export async function lintSubcommand(args) {
|
|
199
|
+
const logger = c8ctl.getLogger();
|
|
200
|
+
const usage = "Usage: c8ctl bpmn lint [<file.bpmn>] [--quiet | -q]";
|
|
201
|
+
const endOfOpts = args.indexOf("--");
|
|
202
|
+
const optionArgs = endOfOpts === -1 ? args : args.slice(0, endOfOpts);
|
|
203
|
+
const positionalArgs = endOfOpts === -1 ? [] : args.slice(endOfOpts + 1);
|
|
204
|
+
const quiet = optionArgs.includes("--quiet") || optionArgs.includes("-q");
|
|
205
|
+
const unknownFlag = optionArgs.find((a) => a.startsWith("-") && a !== "--quiet" && a !== "-q");
|
|
206
|
+
if (unknownFlag) {
|
|
207
|
+
throw new Error(`Unknown flag: ${unknownFlag}. ${usage}`);
|
|
208
|
+
}
|
|
209
|
+
const filePath = positionalArgs[0] ?? optionArgs.find((a) => !a.startsWith("-"));
|
|
210
|
+
// Reject extra positional args (only one BPMN file is accepted).
|
|
211
|
+
const allPositionals = [
|
|
212
|
+
...positionalArgs,
|
|
213
|
+
...optionArgs.filter((a) => !a.startsWith("-")),
|
|
214
|
+
];
|
|
215
|
+
if (allPositionals.length > 1) {
|
|
216
|
+
throw new Error(`Unexpected argument: ${allPositionals[1]}. ${usage}`);
|
|
217
|
+
}
|
|
218
|
+
const input = await readBpmnInput(filePath);
|
|
219
|
+
if (!input) {
|
|
220
|
+
throw new Error("No BPMN input provided. Pass a file path or pipe BPMN XML via stdin.");
|
|
221
|
+
}
|
|
222
|
+
const BpmnModdle = (await import("bpmn-moddle")).default;
|
|
223
|
+
const zeebeSchema = (await import("zeebe-bpmn-moddle/resources/zeebe.json", {
|
|
224
|
+
with: { type: "json" },
|
|
225
|
+
})).default;
|
|
226
|
+
const moddle = new BpmnModdle({ zeebe: zeebeSchema });
|
|
227
|
+
let rootElement;
|
|
228
|
+
try {
|
|
229
|
+
const result = await moddle.fromXML(input.xml);
|
|
230
|
+
rootElement = result.rootElement;
|
|
231
|
+
}
|
|
232
|
+
catch (error) {
|
|
233
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
234
|
+
throw new Error(`Failed to parse BPMN: ${message}`);
|
|
235
|
+
}
|
|
236
|
+
const config = buildLintConfig(rootElement);
|
|
237
|
+
const { Linter } = require("bpmnlint");
|
|
238
|
+
const NodeResolver = require("bpmnlint/lib/resolver/node-resolver");
|
|
239
|
+
// Pass our plugin-scoped `require` to NodeResolver so bpmnlint resolves
|
|
240
|
+
// `bpmnlint-plugin-camunda-compat` from c8ctl's installation, not the
|
|
241
|
+
// user's CWD. Without this, `bpmn lint` only works when run from a
|
|
242
|
+
// directory that happens to have the plugin in its node_modules.
|
|
243
|
+
const linter = new Linter({
|
|
244
|
+
config,
|
|
245
|
+
resolver: new NodeResolver({ require }),
|
|
246
|
+
});
|
|
247
|
+
const results = await linter.lint(rootElement);
|
|
248
|
+
const result = collectLintResult(results);
|
|
249
|
+
if (c8ctl.outputMode === "json") {
|
|
250
|
+
renderLintJson(logger, input.source, result);
|
|
251
|
+
}
|
|
252
|
+
else {
|
|
253
|
+
renderLintText(logger, input.source, result, { quiet });
|
|
254
|
+
}
|
|
255
|
+
if (result.errorCount > 0) {
|
|
256
|
+
process.exitCode = 1;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
//# sourceMappingURL=lint.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lint.js","sourceRoot":"","sources":["../../../default-plugins/bpmn/lint.ts"],"names":[],"mappings":"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"}
|
|
@@ -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
|
+
```
|