@bpmn-ld/bpmn-ld 0.1.0 → 0.2.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/dist/bpmn-ld-cli.d.ts +1 -0
- package/dist/bpmn-ld-cli.js +8 -1
- package/dist/cheat-sheet-catalog.d.ts +10 -0
- package/dist/cheat-sheet-catalog.js +72 -0
- package/dist/cheat-sheet-cli.d.ts +1 -0
- package/dist/cheat-sheet-cli.js +7 -0
- package/dist/cheat-sheet-compose.d.ts +13 -0
- package/dist/cheat-sheet-compose.js +107 -0
- package/dist/cheat-sheet-run.d.ts +11 -0
- package/dist/cheat-sheet-run.js +65 -0
- package/dist/cheat-sheet-svg.d.ts +2 -0
- package/dist/cheat-sheet-svg.js +2 -0
- package/dist/cheat-sheet.d.ts +2 -0
- package/dist/cheat-sheet.js +2 -0
- package/package.json +2 -1
- package/reference/bpmn-xsd/BPMN20.xsd +37 -0
- package/reference/bpmn-xsd/BPMNDI.xsd +100 -0
- package/reference/bpmn-xsd/DC.xsd +29 -0
- package/reference/bpmn-xsd/DI.xsd +100 -0
- package/reference/bpmn-xsd/Semantic.xsd +1562 -0
- package/reference/rospocher/ATTRIBUTION.md +22 -0
- package/reference/rospocher/BPMNOntology.owl +8937 -0
- package/reference/rospocher-verified.json +221 -0
package/dist/bpmn-ld-cli.d.ts
CHANGED
package/dist/bpmn-ld-cli.js
CHANGED
|
@@ -1,16 +1,18 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
1
2
|
import { runAnalyze } from "./analyze-run.js";
|
|
2
3
|
import { runCheckXml } from "./check-xml-run.js";
|
|
3
4
|
import { runConvert } from "./convert-run.js";
|
|
4
5
|
import { runExport } from "./export-run.js";
|
|
5
6
|
import { runLayout } from "./layout-run.js";
|
|
6
7
|
import { runRender } from "./render-run.js";
|
|
8
|
+
import { runCheatSheet } from "./cheat-sheet-run.js";
|
|
7
9
|
import { runInstallSkill } from "./install-skill-run.js";
|
|
8
10
|
import { runValidate } from "./validate-run.js";
|
|
9
11
|
import { ROOT } from "./paths.js";
|
|
10
12
|
const USAGE = `Usage: bpmn-ld <command> [args]
|
|
11
13
|
|
|
12
14
|
Commands:
|
|
13
|
-
validate, analyze, convert, export, layout, check-xml, render
|
|
15
|
+
validate, analyze, convert, export, layout, check-xml, render, cheat-sheet
|
|
14
16
|
coverage, docs
|
|
15
17
|
root, install-skill
|
|
16
18
|
|
|
@@ -64,6 +66,11 @@ const run = async (argv) => {
|
|
|
64
66
|
write(r);
|
|
65
67
|
return r.exitCode;
|
|
66
68
|
}
|
|
69
|
+
case "cheat-sheet": {
|
|
70
|
+
const r = runCheatSheet(rest);
|
|
71
|
+
write(r);
|
|
72
|
+
return r.exitCode;
|
|
73
|
+
}
|
|
67
74
|
case "root": {
|
|
68
75
|
process.stdout.write(`${ROOT}\n`);
|
|
69
76
|
return 0;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface CheatSheetEntry {
|
|
2
|
+
category: string;
|
|
3
|
+
name: string;
|
|
4
|
+
draw: (x: number, y: number) => string;
|
|
5
|
+
explanation: string;
|
|
6
|
+
}
|
|
7
|
+
export declare const cheatSheetCatalog: CheatSheetEntry[];
|
|
8
|
+
export declare const CATALOG: CheatSheetEntry[];
|
|
9
|
+
export declare const catalog: CheatSheetEntry[];
|
|
10
|
+
export type CatalogEntry = CheatSheetEntry;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { eventCircle, taskRect, gatewayDiamond, doubleRect, thickRect, poolRect, laneRect, dataObject, dataStore } from "./render/symbols.js";
|
|
2
|
+
export const cheatSheetCatalog = [];
|
|
3
|
+
const add = (category, name, draw, explanation) => {
|
|
4
|
+
cheatSheetCatalog.push({ category, name, draw, explanation });
|
|
5
|
+
};
|
|
6
|
+
const timerIcon = (x, y) => {
|
|
7
|
+
const cx = x + 10;
|
|
8
|
+
const cy = y + 10;
|
|
9
|
+
const mr = 6;
|
|
10
|
+
return `<circle cx="${cx}" cy="${cy}" r="${mr}" fill="none" stroke="black" stroke-width="1.2"/><line x1="${cx}" y1="${cy}" x2="${cx}" y2="${cy - mr + 2}" stroke="black" stroke-width="1.2"/><line x1="${cx}" y1="${cy}" x2="${cx + mr - 2}" y2="${cy}" stroke="black" stroke-width="1.2"/>`;
|
|
11
|
+
};
|
|
12
|
+
const ev = (stroke = 1.5, dashed = false) => (x, y, inner = "") => {
|
|
13
|
+
const r = 10;
|
|
14
|
+
const cx = x + r;
|
|
15
|
+
const cy = y + r;
|
|
16
|
+
const parts = [`<circle cx="${cx}" cy="${cy}" r="${r}" fill="white" stroke="black" stroke-width="${stroke}"${dashed ? ' stroke-dasharray="4 3"' : ""}/>`, `<circle cx="${cx}" cy="${cy}" r="${r - 3}" fill="none" stroke="black" stroke-width="1.2"/>`];
|
|
17
|
+
if (inner)
|
|
18
|
+
parts.push(inner);
|
|
19
|
+
return parts.join("");
|
|
20
|
+
};
|
|
21
|
+
add("Events", "Start Event", (x, y) => ev(1.5, false)(x, y), "Begins a process; triggered once when the process starts.");
|
|
22
|
+
add("Events", "Intermediate Event", (x, y) => ev(1.5, false)(x, y), "Occurs during flow execution, catching or throwing an event.");
|
|
23
|
+
add("Events", "End Event", (x, y) => ev(3, false)(x, y), "Terminates a path or the whole process instance.");
|
|
24
|
+
add("Events", "Non-interrupting Boundary", (x, y) => ev(1.5, true)(x, y), "Boundary event that does not cancel the activity.");
|
|
25
|
+
add("Events", "Timer Event", (x, y) => eventCircle(x + 10, y + 10, 10, 1.5, false) + timerIcon(x, y), "Fires on a date, cycle, or duration condition.");
|
|
26
|
+
add("Events", "Message Event", (x, y) => eventCircle(x + 10, y + 10, 10, 1.5, false) + `<rect x="${x + 5}" y="${y + 5}" width="10" height="7" fill="none" stroke="black" stroke-width="1.2"/>`, "Sends or receives a message between participants.");
|
|
27
|
+
add("Events", "Error Event", (x, y) => eventCircle(x + 10, y + 10, 10, 1.5, false) + `<polygon points="${x + 10},${y + 4} ${x + 14},${y + 16} ${x + 6},${y + 16}" fill="black" stroke="black" stroke-width="1.2"/>`, "Handles an error thrown by a failed activity.");
|
|
28
|
+
add("Events", "Signal Event", (x, y) => eventCircle(x + 10, y + 10, 10, 1.5, false) + `<polygon points="${x + 10},${y + 4} ${x + 16},${y + 16} ${x + 4},${y + 16}" fill="black" stroke="black" stroke-width="1.2"/>`, "Broadcasts or catches a signal across processes.");
|
|
29
|
+
add("Events", "Escalation Event", (x, y) => eventCircle(x + 10, y + 10, 10, 1.5, false) + `<polygon points="${x + 10},${y + 3} ${x + 16},${y + 17} ${x + 4},${y + 17}" fill="black" stroke="black" stroke-width="1.2"/>`, "Raises an escalation to an enclosing subprocess.");
|
|
30
|
+
add("Events", "Compensation Event", (x, y) => eventCircle(x + 10, y + 10, 10, 1.5, false) + `<polygon points="${x + 4},${y + 6} ${x + 10},${y + 6} ${x + 7},${y + 14} ${x + 13},${y + 14}" fill="black" stroke="black" stroke-width="1.2"/>`, "Triggers or confirms compensation.");
|
|
31
|
+
add("Events", "Conditional Event", (x, y) => eventCircle(x + 10, y + 10, 10, 1.5, false) + `<rect x="${x + 5}" y="${y + 5}" width="10" height="10" fill="black" stroke="black" stroke-width="1.2"/>`, "Fires when a condition becomes true.");
|
|
32
|
+
add("Events", "Link Event", (x, y) => eventCircle(x + 10, y + 10, 10, 1.5, false) + `<circle cx="${x + 10}" cy="${y + 10}" r="5" fill="black" stroke="black" stroke-width="1.2"/>`, "Connects two points in a large process.");
|
|
33
|
+
add("Events", "Cancel Event", (x, y) => eventCircle(x + 10, y + 10, 10, 1.5, false) + `<line x1="${x + 4}" y1="${y + 4}" x2="${x + 16}" y2="${y + 16}" stroke="black" stroke-width="1.5"/><line x1="${x + 16}" y1="${y + 4}" x2="${x + 4}" y2="${y + 16}" stroke="black" stroke-width="1.5"/>`, "Cancels a transaction subprocess.");
|
|
34
|
+
add("Events", "Terminate Event", (x, y) => eventCircle(x + 10, y + 10, 10, 3, false) + `<circle cx="${x + 10}" cy="${y + 10}" r="5" fill="black" stroke="black" stroke-width="1.2"/>`, "Ends all running tokens in the process.");
|
|
35
|
+
add("Events", "Multiple Event", (x, y) => eventCircle(x + 10, y + 10, 10, 1.5, false) + `<polygon points="${x + 10},${y + 4} ${x + 16},${y + 6} ${x + 14},${y + 14} ${x + 6},${y + 14} ${x + 4},${y + 6}" fill="black" stroke="black" stroke-width="1.2"/>`, "Triggered when any listed condition occurs.");
|
|
36
|
+
add("Events", "Parallel Multiple Event", (x, y) => eventCircle(x + 10, y + 10, 10, 1.5, false) + `<line x1="${x + 4}" y1="${y + 10}" x2="${x + 16}" y2="${y + 10}" stroke="black" stroke-width="1.2"/><line x1="${x + 10}" y1="${y + 4}" x2="${x + 10}" y2="${y + 16}" stroke="black" stroke-width="1.2"/>`, "Requires all listed events to have occurred.");
|
|
37
|
+
const task = (x, y, iconSvg) => taskRect(x, y, 34, 22) + (iconSvg ? iconSvg.replace(/__x__/g, String(x + 10)).replace(/__y__/g, String(y + 4)) : "");
|
|
38
|
+
add("Activities", "Task", (x, y) => taskRect(x, y, 34, 22), "Performs work that is not otherwise specialised.");
|
|
39
|
+
add("Activities", "User Task", (x, y) => taskRect(x, y, 34, 22) + `<circle cx="${x + 17}" cy="${y + 9}" r="4" fill="none" stroke="black" stroke-width="1.2"/><line x1="${x + 17}" y1="${y + 13}" x2="${x + 17}" y2="${y + 18}" stroke="black" stroke-width="1.2"/>`, "Human work item performed by a person.");
|
|
40
|
+
add("Activities", "Service Task", (x, y) => taskRect(x, y, 34, 22) + `<path d="M ${x + 17} ${y + 5} l 3 4 4 1 -4 1 -3 4 -3 -4 -4 -1 4 -1 z" fill="none" stroke="black" stroke-width="1.2"/>`, "Automated work performed by a service.");
|
|
41
|
+
add("Activities", "Script Task", (x, y) => taskRect(x, y, 34, 22) + `<rect x="${x + 10}" y="${y + 6}" width="14" height="10" fill="none" stroke="black" stroke-width="1.2"/>`, "Executes a script within the engine.");
|
|
42
|
+
add("Activities", "Send Task", (x, y) => taskRect(x, y, 34, 22) + `<polygon points="${x + 10},${y + 11} ${x + 24},${y + 4} ${x + 24},${y + 18}" fill="none" stroke="black" stroke-width="1.2"/>`, "Sends a message to another participant.");
|
|
43
|
+
add("Activities", "Receive Task", (x, y) => taskRect(x, y, 34, 22) + `<polygon points="${x + 10},${y + 4} ${x + 24},${y + 11} ${x + 10},${y + 18}" fill="none" stroke="black" stroke-width="1.2"/>`, "Waits for and receives a message.");
|
|
44
|
+
add("Activities", "Manual Task", (x, y) => taskRect(x, y, 34, 22) + `<path d="M ${x + 10} ${y + 18} V ${y + 11} M ${x + 14} ${y + 18} V ${y + 9} M ${x + 18} ${y + 18} V ${y + 9}" stroke="black" stroke-width="1.2" fill="none"/>`, "Work done by a person outside the system.");
|
|
45
|
+
add("Activities", "Business Rule Task", (x, y) => taskRect(x, y, 34, 22) + `<rect x="${x + 13}" y="${y + 7}" width="8" height="8" fill="none" stroke="black" stroke-width="1.2"/>`, "Invokes a decision or rules service.");
|
|
46
|
+
add("Activities", "Subprocess", (x, y) => taskRect(x, y, 34, 22) + `<line x1="${x + 13}" y1="${y + 11}" x2="${x + 21}" y2="${y + 11}" stroke="black" stroke-width="1.5"/><line x1="${x + 17}" y1="${y + 7}" x2="${x + 17}" y2="${y + 15}" stroke="black" stroke-width="1.5"/>`, "Embedded subprocess with its own scope.");
|
|
47
|
+
add("Activities", "Ad-hoc Subprocess", (x, y) => taskRect(x, y, 34, 22) + `<text x="${x + 4}" y="${y + 16}" font-family="sans-serif" font-size="14" fill="black">~</text>`, "Subprocess with unordered inner activities.");
|
|
48
|
+
add("Activities", "Transaction", (x, y) => doubleRect(x, y, 34, 22), "All-or-nothing subprocess boundary.");
|
|
49
|
+
add("Activities", "Call Activity", (x, y) => thickRect(x, y, 34, 22), "Reusable callable subprocess (thick border).");
|
|
50
|
+
add("Markers", "Loop Marker", (x, y) => `<path d="M ${x + 18} ${y + 11} a 6 6 0 1 1 -6 6" fill="none" stroke="black" stroke-width="1.2"/>`, "Repeats until a condition is met.");
|
|
51
|
+
add("Markers", "Sequential Multi-instance", (x, y) => `<line x1="${x + 10}" y1="${y + 5}" x2="${x + 10}" y2="${y + 17}" stroke="black" stroke-width="1.2"/><line x1="${x + 14}" y1="${y + 5}" x2="${x + 14}" y2="${y + 17}" stroke="black" stroke-width="1.2"/><line x1="${x + 18}" y1="${y + 5}" x2="${x + 18}" y2="${y + 17}" stroke="black" stroke-width="1.2"/>`, "Creates instances processed one after another.");
|
|
52
|
+
add("Markers", "Parallel Multi-instance", (x, y) => `<line x1="${x + 10}" y1="${y + 11}" x2="${x + 18}" y2="${y + 5}" stroke="black" stroke-width="1.2"/><line x1="${x + 10}" y1="${y + 11}" x2="${x + 18}" y2="${y + 11}" stroke="black" stroke-width="1.2"/><line x1="${x + 10}" y1="${y + 11}" x2="${x + 18}" y2="${y + 17}" stroke="black" stroke-width="1.2"/>`, "Creates instances processed concurrently.");
|
|
53
|
+
add("Markers", "Compensation Marker", (x, y) => `<polygon points="${x + 6},${y + 3} ${x + 2},${y + 8} ${x + 6},${y + 13}" fill="black"/><polygon points="${x + 12},${y + 3} ${x + 8},${y + 8} ${x + 12},${y + 13}" fill="black"/>`, "Marks a compensation handler.");
|
|
54
|
+
add("Gateways", "Exclusive Gateway", (x, y) => { const cx = x + 17, cy = y + 11, s = 12; return gatewayDiamond(cx, cy, s) + `<line x1="${cx - 4}" y1="${cy - 4}" x2="${cx + 4}" y2="${cy + 4}" stroke="black" stroke-width="1.5"/><line x1="${cx + 4}" y1="${cy - 4}" x2="${cx - 4}" y2="${cy + 4}" stroke="black" stroke-width="1.5"/>`; }, "One outgoing path is taken based on conditions.");
|
|
55
|
+
add("Gateways", "Inclusive Gateway", (x, y) => { const cx = x + 17, cy = y + 11, s = 12; return gatewayDiamond(cx, cy, s) + `<circle cx="${cx}" cy="${cy}" r="4" fill="none" stroke="black" stroke-width="1.5"/>`; }, "One or more paths may be taken.");
|
|
56
|
+
add("Gateways", "Parallel Gateway", (x, y) => { const cx = x + 17, cy = y + 11, s = 12; return gatewayDiamond(cx, cy, s) + `<line x1="${cx - 4}" y1="${cy}" x2="${cx + 4}" y2="${cy}" stroke="black" stroke-width="1.5"/><line x1="${cx}" y1="${cy - 4}" x2="${cx}" y2="${cy + 4}" stroke="black" stroke-width="1.5"/>`; }, "All outgoing paths are taken concurrently.");
|
|
57
|
+
add("Gateways", "Event-Based Gateway", (x, y) => { const cx = x + 17, cy = y + 11, s = 12; return gatewayDiamond(cx, cy, s) + `<polygon points="${cx},${cy - 4} ${cx + 4},${cy} ${cx},${cy + 4} ${cx - 4},${cy}" fill="none" stroke="black" stroke-width="1.5"/>`; }, "Waits for one of several events before continuing.");
|
|
58
|
+
add("Gateways", "Complex Gateway", (x, y) => { const cx = x + 17, cy = y + 11, s = 12; return gatewayDiamond(cx, cy, s) + `<text x="${cx}" y="${cy + 4}" text-anchor="middle" font-family="sans-serif" font-size="12" fill="black">*</text>`; }, "Custom merge/fork semantics with conditions.");
|
|
59
|
+
add("Flows", "Sequence Flow", (x, y) => `<line x1="${x}" y1="${y + 11}" x2="${x + 30}" y2="${y + 11}" stroke="black" stroke-width="1.5" marker-end="url(#arrow)"/>`, "Control passes from one element to the next.");
|
|
60
|
+
add("Flows", "Default Flow", (x, y) => `<line x1="${x}" y1="${y + 11}" x2="${x + 30}" y2="${y + 11}" stroke="black" stroke-width="1.5" marker-end="url(#arrow)"/><path d="M ${x + 12} ${y + 6} L ${x + 18} ${y + 11} L ${x + 12} ${y + 16}" fill="none" stroke="black" stroke-width="1.2"/>`, "Taken when no other condition matches.");
|
|
61
|
+
add("Flows", "Conditional Flow", (x, y) => `<line x1="${x}" y1="${y + 11}" x2="${x + 30}" y2="${y + 11}" stroke="black" stroke-width="1.5" stroke-dasharray="6 3" marker-end="url(#arrow)"/><polygon points="${x + 14},${y + 8} ${x + 19},${y + 11} ${x + 14},${y + 14}" fill="black"/>`, "Taken only if its condition holds.");
|
|
62
|
+
add("Flows", "Message Flow", (x, y) => `<line x1="${x}" y1="${y + 11}" x2="${x + 30}" y2="${y + 11}" stroke="black" stroke-width="1.5" stroke-dasharray="6 3" marker-end="url(#arrow-open)"/>`, "Communication between pools or participants.");
|
|
63
|
+
add("Flows", "Association", (x, y) => `<line x1="${x}" y1="${y + 11}" x2="${x + 30}" y2="${y + 11}" stroke="black" stroke-width="1" stroke-dasharray="2 2"/>`, "Relates artifacts to flow elements.");
|
|
64
|
+
add("Flows", "Data Association", (x, y) => `<line x1="${x}" y1="${y + 11}" x2="${x + 30}" y2="${y + 11}" stroke="black" stroke-width="1" stroke-dasharray="2 2" marker-end="url(#arrow-open)"/>`, "Links data to activities or events.");
|
|
65
|
+
add("Data", "Data Object", (x, y) => dataObject(x + 3, y + 4, 28, 16), "Carries business data through the process.");
|
|
66
|
+
add("Data", "Data Store", (x, y) => dataStore(x + 3, y + 4, 28, 16), "Persistent shared data repository.");
|
|
67
|
+
add("Organisation", "Pool", (x, y) => poolRect(x + 2, y + 4, 32, 16, true, true), "Represents a participant in collaboration.");
|
|
68
|
+
add("Organisation", "Lane", (x, y) => laneRect(x + 2, y + 4, 32, 16, true), "Partitions a pool by role or responsibility.");
|
|
69
|
+
add("Annotations/Groups", "Text Annotation", (x, y) => `<rect x="${x + 2}" y="${y + 4}" width="26" height="16" fill="none" stroke="black" stroke-width="1" stroke-dasharray="4 2"/>`, "Provides extra textual information.");
|
|
70
|
+
add("Annotations/Groups", "Group", (x, y) => `<rect x="${x + 2}" y="${y + 4}" width="28" height="16" fill="none" stroke="black" stroke-width="1.5" stroke-dasharray="6 3" rx="6" ry="6"/>`, "Visually groups related elements.");
|
|
71
|
+
export const CATALOG = cheatSheetCatalog;
|
|
72
|
+
export const catalog = cheatSheetCatalog;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type CheatSheetEntry } from "./cheat-sheet-catalog.ts";
|
|
2
|
+
export interface ComposeOptions {
|
|
3
|
+
catalog?: CheatSheetEntry[];
|
|
4
|
+
version?: string;
|
|
5
|
+
}
|
|
6
|
+
export declare const getVersion: () => string;
|
|
7
|
+
export declare const composeCheatSheet: (options?: ComposeOptions) => string;
|
|
8
|
+
export declare const compose: typeof composeCheatSheet;
|
|
9
|
+
export declare const buildSvg: typeof composeCheatSheet;
|
|
10
|
+
export declare const renderCheatSheet: typeof composeCheatSheet;
|
|
11
|
+
export declare const composeCheatSheetSvg: typeof composeCheatSheet;
|
|
12
|
+
export declare const build: typeof composeCheatSheet;
|
|
13
|
+
export declare const generate: typeof composeCheatSheet;
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { resolve } from "node:path";
|
|
3
|
+
import { ROOT } from "./paths.js";
|
|
4
|
+
import { cheatSheetCatalog } from "./cheat-sheet-catalog.js";
|
|
5
|
+
export const getVersion = () => {
|
|
6
|
+
try {
|
|
7
|
+
const pkg = JSON.parse(readFileSync(resolve(ROOT, "package.json"), "utf8"));
|
|
8
|
+
return String(pkg.version ?? "0.0.0");
|
|
9
|
+
}
|
|
10
|
+
catch {
|
|
11
|
+
return "0.0.0";
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
export const composeCheatSheet = (options = {}) => {
|
|
15
|
+
const catalog = options.catalog ?? cheatSheetCatalog;
|
|
16
|
+
const version = options.version ?? getVersion();
|
|
17
|
+
const W = 595;
|
|
18
|
+
const H = 842;
|
|
19
|
+
const margin = 34;
|
|
20
|
+
const innerW = W - margin * 2;
|
|
21
|
+
const colW = (innerW - 12) / 2;
|
|
22
|
+
const glyphW = 44;
|
|
23
|
+
const titleY = margin + 20;
|
|
24
|
+
const subtitleY = titleY + 16;
|
|
25
|
+
const footerY = H - margin + 4;
|
|
26
|
+
const contentTop = subtitleY + 18;
|
|
27
|
+
const contentBottom = footerY - 18;
|
|
28
|
+
const availableH = contentBottom - contentTop;
|
|
29
|
+
const items = [];
|
|
30
|
+
let currentCat = "";
|
|
31
|
+
for (const entry of catalog) {
|
|
32
|
+
if (entry.category !== currentCat) {
|
|
33
|
+
currentCat = entry.category;
|
|
34
|
+
items.push({ type: "banner", category: currentCat });
|
|
35
|
+
}
|
|
36
|
+
items.push({ type: "row", entry });
|
|
37
|
+
}
|
|
38
|
+
const totalUnits = items.reduce((acc, it) => acc + (it.type === "banner" ? 1.4 : 1), 0);
|
|
39
|
+
const rowH = Math.max(12, Math.min(20, availableH / totalUnits));
|
|
40
|
+
const left = [];
|
|
41
|
+
const right = [];
|
|
42
|
+
const mid = Math.ceil(items.length / 2);
|
|
43
|
+
const leftItems = items.slice(0, mid);
|
|
44
|
+
const rightItems = items.slice(mid);
|
|
45
|
+
const esc = (v) => v.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
46
|
+
const wrap = (text, maxPx) => {
|
|
47
|
+
const chars = Math.max(8, Math.floor(maxPx / 4.6));
|
|
48
|
+
const words = text.split(/\s+/);
|
|
49
|
+
const lines = [];
|
|
50
|
+
let cur = "";
|
|
51
|
+
for (const w of words) {
|
|
52
|
+
const cand = cur === "" ? w : `${cur} ${w}`;
|
|
53
|
+
if (cur !== "" && cand.length > chars) {
|
|
54
|
+
lines.push(cur);
|
|
55
|
+
cur = w;
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
cur = cand;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if (cur !== "")
|
|
62
|
+
lines.push(cur);
|
|
63
|
+
return lines;
|
|
64
|
+
};
|
|
65
|
+
const renderBanner = (y, cat, colStartX, width) => {
|
|
66
|
+
const by = y + rowH * 0.3;
|
|
67
|
+
return `<rect x="${colStartX}" y="${by}" width="${width}" height="${rowH * 0.85}" fill="#e8e8e8" stroke="black" stroke-width="0.8"/><text x="${colStartX + 6}" y="${by + rowH * 0.6}" font-family="sans-serif" font-size="11" font-weight="bold" fill="black">${esc(cat)}</text>`;
|
|
68
|
+
};
|
|
69
|
+
const place = (list, startItems, startX) => {
|
|
70
|
+
let y = contentTop;
|
|
71
|
+
for (const it of startItems) {
|
|
72
|
+
if (it.type === "banner") {
|
|
73
|
+
list.push(renderBanner(y, it.category, startX, colW));
|
|
74
|
+
y += rowH * 1.4;
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
const entry = it.entry;
|
|
78
|
+
const gy = y + (rowH - 22) / 2;
|
|
79
|
+
list.push(`<g>${entry.draw(startX + 4, gy)}</g>`);
|
|
80
|
+
const lines = wrap(entry.explanation, colW - glyphW - 4);
|
|
81
|
+
lines.slice(0, 2).forEach((ln, i) => {
|
|
82
|
+
list.push(`<text x="${startX + glyphW}" y="${y + 9 + i * 10}" font-family="sans-serif" font-size="8.5" fill="black">${esc(ln)}</text>`);
|
|
83
|
+
});
|
|
84
|
+
y += rowH;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
place(left, leftItems, margin);
|
|
89
|
+
place(right, rightItems, margin + colW + 12);
|
|
90
|
+
const defs = `<defs><marker id="arrow" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" fill="black"/></marker><marker id="arrow-open" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10" fill="none" stroke="black" stroke-width="1.2"/></marker></defs>`;
|
|
91
|
+
return [
|
|
92
|
+
`<svg xmlns="http://www.w3.org/2000/svg" width="${W}" height="${H}" viewBox="0 0 ${W} ${H}">`,
|
|
93
|
+
defs,
|
|
94
|
+
`<text x="${W / 2}" y="${titleY}" text-anchor="middle" font-family="sans-serif" font-size="18" font-weight="bold" fill="black">BPMN 2.0 Cheat Sheet</text>`,
|
|
95
|
+
`<text x="${W / 2}" y="${subtitleY}" text-anchor="middle" font-family="sans-serif" font-size="10" fill="black">A one-page reference to the BPMN 2.0 notation vocabulary</text>`,
|
|
96
|
+
...left,
|
|
97
|
+
...right,
|
|
98
|
+
`<text x="${W / 2}" y="${footerY}" text-anchor="middle" font-family="sans-serif" font-size="9" fill="black">bpmn-ld ${esc(version)}</text>`,
|
|
99
|
+
`</svg>`,
|
|
100
|
+
].join("");
|
|
101
|
+
};
|
|
102
|
+
export const compose = composeCheatSheet;
|
|
103
|
+
export const buildSvg = composeCheatSheet;
|
|
104
|
+
export const renderCheatSheet = composeCheatSheet;
|
|
105
|
+
export const composeCheatSheetSvg = composeCheatSheet;
|
|
106
|
+
export const build = composeCheatSheet;
|
|
107
|
+
export const generate = composeCheatSheet;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare const EXIT_OK = 0;
|
|
2
|
+
export declare const EXIT_BAD_INPUT = 2;
|
|
3
|
+
export interface CliResult {
|
|
4
|
+
exitCode: number;
|
|
5
|
+
stdout: string;
|
|
6
|
+
stderr: string;
|
|
7
|
+
}
|
|
8
|
+
export declare const USAGE = "Usage: cheat-sheet [options]\n\nGenerates a BPMN 2.0 cheat sheet SVG.\n\nOptions:\n -o, --output <file> Write SVG to <file> (use - for stdout)\n -h, --help Show this help\n\nExit codes:\n 0 Generated successfully\n 2 Usage error\n";
|
|
9
|
+
export declare const runCheatSheet: (argv: string[]) => CliResult;
|
|
10
|
+
export declare const runCheatSheetRun: typeof runCheatSheet;
|
|
11
|
+
export declare const run: typeof runCheatSheet;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { writeFileSync } from "node:fs";
|
|
2
|
+
import { composeCheatSheet, getVersion } from "./cheat-sheet-compose.js";
|
|
3
|
+
export const EXIT_OK = 0;
|
|
4
|
+
export const EXIT_BAD_INPUT = 2;
|
|
5
|
+
export const USAGE = `Usage: cheat-sheet [options]
|
|
6
|
+
|
|
7
|
+
Generates a BPMN 2.0 cheat sheet SVG.
|
|
8
|
+
|
|
9
|
+
Options:
|
|
10
|
+
-o, --output <file> Write SVG to <file> (use - for stdout)
|
|
11
|
+
-h, --help Show this help
|
|
12
|
+
|
|
13
|
+
Exit codes:
|
|
14
|
+
0 Generated successfully
|
|
15
|
+
2 Usage error
|
|
16
|
+
`;
|
|
17
|
+
class UsageError extends Error {
|
|
18
|
+
}
|
|
19
|
+
const parseArgs = (argv) => {
|
|
20
|
+
const options = {};
|
|
21
|
+
for (let i = 0; i < argv.length; i++) {
|
|
22
|
+
const arg = argv[i];
|
|
23
|
+
if (arg === "-h" || arg === "--help")
|
|
24
|
+
return "help";
|
|
25
|
+
else if (arg === "-o" || arg === "--output") {
|
|
26
|
+
const value = argv[++i];
|
|
27
|
+
if (value === undefined || value.startsWith("-") && value !== "-")
|
|
28
|
+
throw new UsageError(`${arg} requires a value`);
|
|
29
|
+
options.output = value;
|
|
30
|
+
}
|
|
31
|
+
else if (arg.startsWith("-"))
|
|
32
|
+
throw new UsageError(`unknown option ${arg}`);
|
|
33
|
+
else
|
|
34
|
+
throw new UsageError(`unexpected argument ${arg}`);
|
|
35
|
+
}
|
|
36
|
+
return options;
|
|
37
|
+
};
|
|
38
|
+
const failure = (stderr) => ({ exitCode: EXIT_BAD_INPUT, stdout: "", stderr });
|
|
39
|
+
export const runCheatSheet = (argv) => {
|
|
40
|
+
let options;
|
|
41
|
+
try {
|
|
42
|
+
options = parseArgs(argv);
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
45
|
+
if (error instanceof UsageError)
|
|
46
|
+
return failure(`error: ${error.message}\n\n${USAGE}`);
|
|
47
|
+
throw error;
|
|
48
|
+
}
|
|
49
|
+
if (options === "help")
|
|
50
|
+
return { exitCode: EXIT_OK, stdout: USAGE, stderr: "" };
|
|
51
|
+
const svg = composeCheatSheet();
|
|
52
|
+
const out = options.output ?? "bpmn-2.0-cheat-sheet.svg";
|
|
53
|
+
if (out === "-") {
|
|
54
|
+
return { exitCode: EXIT_OK, stdout: svg + "\n", stderr: "" };
|
|
55
|
+
}
|
|
56
|
+
try {
|
|
57
|
+
writeFileSync(out, svg + "\n", "utf8");
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
return failure(`error: cannot write ${out}: ${error.message}\n`);
|
|
61
|
+
}
|
|
62
|
+
return { exitCode: EXIT_OK, stdout: "", stderr: "" };
|
|
63
|
+
};
|
|
64
|
+
export const runCheatSheetRun = runCheatSheet;
|
|
65
|
+
export const run = runCheatSheet;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bpmn-ld/bpmn-ld",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "A Semantic JSON-LD Representation of BPMN 2.0",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"BPMN",
|
|
@@ -62,6 +62,7 @@
|
|
|
62
62
|
},
|
|
63
63
|
"files": [
|
|
64
64
|
"dist",
|
|
65
|
+
"reference",
|
|
65
66
|
"contexts",
|
|
66
67
|
"ontology",
|
|
67
68
|
"schema",
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<xsd:schema elementFormDefault="qualified" attributeFormDefault="unqualified"
|
|
3
|
+
xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
|
|
4
|
+
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
|
5
|
+
xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
|
|
6
|
+
targetNamespace="http://www.omg.org/spec/BPMN/20100524/MODEL">
|
|
7
|
+
|
|
8
|
+
<xsd:import namespace="http://www.omg.org/spec/BPMN/20100524/DI" schemaLocation="BPMNDI.xsd"/>
|
|
9
|
+
<xsd:include schemaLocation="Semantic.xsd"/>
|
|
10
|
+
|
|
11
|
+
<xsd:element name="definitions" type="tDefinitions"/>
|
|
12
|
+
<xsd:complexType name="tDefinitions">
|
|
13
|
+
<xsd:sequence>
|
|
14
|
+
<xsd:element ref="import" minOccurs="0" maxOccurs="unbounded"/>
|
|
15
|
+
<xsd:element ref="extension" minOccurs="0" maxOccurs="unbounded"/>
|
|
16
|
+
<xsd:element ref="rootElement" minOccurs="0" maxOccurs="unbounded"/>
|
|
17
|
+
<xsd:element ref="bpmndi:BPMNDiagram" minOccurs="0" maxOccurs="unbounded"/>
|
|
18
|
+
<xsd:element ref="relationship" minOccurs="0" maxOccurs="unbounded"/>
|
|
19
|
+
</xsd:sequence>
|
|
20
|
+
<xsd:attribute name="id" type="xsd:ID" use="optional"/>
|
|
21
|
+
<xsd:attribute name="name" type="xsd:string"/>
|
|
22
|
+
<xsd:attribute name="targetNamespace" type="xsd:anyURI" use="required"/>
|
|
23
|
+
<xsd:attribute name="expressionLanguage" type="xsd:anyURI" use="optional" default="http://www.w3.org/1999/XPath"/>
|
|
24
|
+
<xsd:attribute name="typeLanguage" type="xsd:anyURI" use="optional" default="http://www.w3.org/2001/XMLSchema"/>
|
|
25
|
+
<xsd:attribute name="exporter" type="xsd:string"/>
|
|
26
|
+
<xsd:attribute name="exporterVersion" type="xsd:string"/>
|
|
27
|
+
<xsd:anyAttribute namespace="##other" processContents="lax"/>
|
|
28
|
+
</xsd:complexType>
|
|
29
|
+
|
|
30
|
+
<xsd:element name="import" type="tImport"/>
|
|
31
|
+
<xsd:complexType name="tImport">
|
|
32
|
+
<xsd:attribute name="namespace" type="xsd:anyURI" use="required"/>
|
|
33
|
+
<xsd:attribute name="location" type="xsd:string" use="required"/>
|
|
34
|
+
<xsd:attribute name="importType" type="xsd:anyURI" use="required"/>
|
|
35
|
+
</xsd:complexType>
|
|
36
|
+
|
|
37
|
+
</xsd:schema>
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" targetNamespace="http://www.omg.org/spec/BPMN/20100524/DI" elementFormDefault="qualified" attributeFormDefault="unqualified">
|
|
3
|
+
|
|
4
|
+
<xsd:import namespace="http://www.omg.org/spec/DD/20100524/DC" schemaLocation="DC.xsd" />
|
|
5
|
+
<xsd:import namespace="http://www.omg.org/spec/DD/20100524/DI" schemaLocation="DI.xsd" />
|
|
6
|
+
|
|
7
|
+
<xsd:element name="BPMNDiagram" type="bpmndi:BPMNDiagram" />
|
|
8
|
+
<xsd:element name="BPMNPlane" type="bpmndi:BPMNPlane" />
|
|
9
|
+
<xsd:element name="BPMNLabelStyle" type="bpmndi:BPMNLabelStyle" />
|
|
10
|
+
<xsd:element name="BPMNShape" type="bpmndi:BPMNShape" substitutionGroup="di:DiagramElement" />
|
|
11
|
+
<xsd:element name="BPMNLabel" type="bpmndi:BPMNLabel" />
|
|
12
|
+
<xsd:element name="BPMNEdge" type="bpmndi:BPMNEdge" substitutionGroup="di:DiagramElement" />
|
|
13
|
+
|
|
14
|
+
<xsd:complexType name="BPMNDiagram">
|
|
15
|
+
<xsd:complexContent>
|
|
16
|
+
<xsd:extension base="di:Diagram">
|
|
17
|
+
<xsd:sequence>
|
|
18
|
+
<xsd:element ref="bpmndi:BPMNPlane" />
|
|
19
|
+
<xsd:element ref="bpmndi:BPMNLabelStyle" maxOccurs="unbounded" minOccurs="0" />
|
|
20
|
+
</xsd:sequence>
|
|
21
|
+
</xsd:extension>
|
|
22
|
+
</xsd:complexContent>
|
|
23
|
+
</xsd:complexType>
|
|
24
|
+
|
|
25
|
+
<xsd:complexType name="BPMNPlane">
|
|
26
|
+
<xsd:complexContent>
|
|
27
|
+
<xsd:extension base="di:Plane">
|
|
28
|
+
<xsd:attribute name="bpmnElement" type="xsd:QName" />
|
|
29
|
+
</xsd:extension>
|
|
30
|
+
</xsd:complexContent>
|
|
31
|
+
</xsd:complexType>
|
|
32
|
+
|
|
33
|
+
<xsd:complexType name="BPMNEdge">
|
|
34
|
+
<xsd:complexContent>
|
|
35
|
+
<xsd:extension base="di:LabeledEdge">
|
|
36
|
+
<xsd:sequence>
|
|
37
|
+
<xsd:element ref="bpmndi:BPMNLabel" minOccurs="0" />
|
|
38
|
+
</xsd:sequence>
|
|
39
|
+
<xsd:attribute name="bpmnElement" type="xsd:QName" />
|
|
40
|
+
<xsd:attribute name="sourceElement" type="xsd:QName" />
|
|
41
|
+
<xsd:attribute name="targetElement" type="xsd:QName" />
|
|
42
|
+
<xsd:attribute name="messageVisibleKind" type="bpmndi:MessageVisibleKind" />
|
|
43
|
+
</xsd:extension>
|
|
44
|
+
</xsd:complexContent>
|
|
45
|
+
</xsd:complexType>
|
|
46
|
+
|
|
47
|
+
<xsd:complexType name="BPMNShape">
|
|
48
|
+
<xsd:complexContent>
|
|
49
|
+
<xsd:extension base="di:LabeledShape">
|
|
50
|
+
<xsd:sequence>
|
|
51
|
+
<xsd:element ref="bpmndi:BPMNLabel" minOccurs="0" />
|
|
52
|
+
</xsd:sequence>
|
|
53
|
+
<xsd:attribute name="bpmnElement" type="xsd:QName" />
|
|
54
|
+
<xsd:attribute name="isHorizontal" type="xsd:boolean" />
|
|
55
|
+
<xsd:attribute name="isExpanded" type="xsd:boolean" />
|
|
56
|
+
<xsd:attribute name="isMarkerVisible" type="xsd:boolean" />
|
|
57
|
+
<xsd:attribute name="isMessageVisible" type="xsd:boolean" />
|
|
58
|
+
<xsd:attribute name="participantBandKind" type="bpmndi:ParticipantBandKind" />
|
|
59
|
+
<xsd:attribute name="choreographyActivityShape" type="xsd:QName"/>
|
|
60
|
+
</xsd:extension>
|
|
61
|
+
</xsd:complexContent>
|
|
62
|
+
</xsd:complexType>
|
|
63
|
+
|
|
64
|
+
<xsd:complexType name="BPMNLabel">
|
|
65
|
+
<xsd:complexContent>
|
|
66
|
+
<xsd:extension base="di:Label">
|
|
67
|
+
<xsd:attribute name="labelStyle" type="xsd:QName" />
|
|
68
|
+
</xsd:extension>
|
|
69
|
+
</xsd:complexContent>
|
|
70
|
+
</xsd:complexType>
|
|
71
|
+
|
|
72
|
+
<xsd:complexType name="BPMNLabelStyle">
|
|
73
|
+
<xsd:complexContent>
|
|
74
|
+
<xsd:extension base="di:Style">
|
|
75
|
+
<xsd:sequence>
|
|
76
|
+
<xsd:element ref="dc:Font" />
|
|
77
|
+
</xsd:sequence>
|
|
78
|
+
</xsd:extension>
|
|
79
|
+
</xsd:complexContent>
|
|
80
|
+
</xsd:complexType>
|
|
81
|
+
|
|
82
|
+
<xsd:simpleType name="ParticipantBandKind">
|
|
83
|
+
<xsd:restriction base="xsd:string">
|
|
84
|
+
<xsd:enumeration value="top_initiating" />
|
|
85
|
+
<xsd:enumeration value="middle_initiating" />
|
|
86
|
+
<xsd:enumeration value="bottom_initiating" />
|
|
87
|
+
<xsd:enumeration value="top_non_initiating" />
|
|
88
|
+
<xsd:enumeration value="middle_non_initiating" />
|
|
89
|
+
<xsd:enumeration value="bottom_non_initiating" />
|
|
90
|
+
</xsd:restriction>
|
|
91
|
+
</xsd:simpleType>
|
|
92
|
+
|
|
93
|
+
<xsd:simpleType name="MessageVisibleKind">
|
|
94
|
+
<xsd:restriction base="xsd:string">
|
|
95
|
+
<xsd:enumeration value="initiating" />
|
|
96
|
+
<xsd:enumeration value="non_initiating" />
|
|
97
|
+
</xsd:restriction>
|
|
98
|
+
</xsd:simpleType>
|
|
99
|
+
|
|
100
|
+
</xsd:schema>
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" targetNamespace="http://www.omg.org/spec/DD/20100524/DC" elementFormDefault="qualified" attributeFormDefault="unqualified">
|
|
3
|
+
|
|
4
|
+
<xsd:element name="Font" type="dc:Font" />
|
|
5
|
+
<xsd:element name="Point" type="dc:Point" />
|
|
6
|
+
<xsd:element name="Bounds" type="dc:Bounds" />
|
|
7
|
+
|
|
8
|
+
<xsd:complexType name="Font">
|
|
9
|
+
<xsd:attribute name="name" type="xsd:string" />
|
|
10
|
+
<xsd:attribute name="size" type="xsd:double" />
|
|
11
|
+
<xsd:attribute name="isBold" type="xsd:boolean" />
|
|
12
|
+
<xsd:attribute name="isItalic" type="xsd:boolean" />
|
|
13
|
+
<xsd:attribute name="isUnderline" type="xsd:boolean" />
|
|
14
|
+
<xsd:attribute name="isStrikeThrough" type="xsd:boolean" />
|
|
15
|
+
</xsd:complexType>
|
|
16
|
+
|
|
17
|
+
<xsd:complexType name="Point">
|
|
18
|
+
<xsd:attribute name="x" type="xsd:double" use="required" />
|
|
19
|
+
<xsd:attribute name="y" type="xsd:double" use="required" />
|
|
20
|
+
</xsd:complexType>
|
|
21
|
+
|
|
22
|
+
<xsd:complexType name="Bounds">
|
|
23
|
+
<xsd:attribute name="x" type="xsd:double" use="required" />
|
|
24
|
+
<xsd:attribute name="y" type="xsd:double" use="required" />
|
|
25
|
+
<xsd:attribute name="width" type="xsd:double" use="required" />
|
|
26
|
+
<xsd:attribute name="height" type="xsd:double" use="required" />
|
|
27
|
+
</xsd:complexType>
|
|
28
|
+
|
|
29
|
+
</xsd:schema>
|