@bpmn-ld/bpmn-ld 0.0.0-stage → 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/LICENSE +201 -0
- package/README.md +125 -2
- package/contexts/combined.jsonld +3 -0
- package/contexts/core.jsonld +170 -0
- package/contexts/di.jsonld +37 -0
- package/dist/analyze/analyze.d.ts +3 -0
- package/dist/analyze/analyze.js +11 -0
- package/dist/analyze/findings.d.ts +8 -0
- package/dist/analyze/findings.js +1 -0
- package/dist/analyze/report.d.ts +3 -0
- package/dist/analyze/report.js +9 -0
- package/dist/analyze/rules/ad-hoc-completion-condition.d.ts +2 -0
- package/dist/analyze/rules/ad-hoc-completion-condition.js +7 -0
- package/dist/analyze/rules/cannot-reach-end.d.ts +2 -0
- package/dist/analyze/rules/cannot-reach-end.js +28 -0
- package/dist/analyze/rules/compensation-association.d.ts +2 -0
- package/dist/analyze/rules/compensation-association.js +13 -0
- package/dist/analyze/rules/dead-end.d.ts +2 -0
- package/dist/analyze/rules/dead-end.js +13 -0
- package/dist/analyze/rules/end-event.d.ts +2 -0
- package/dist/analyze/rules/end-event.js +8 -0
- package/dist/analyze/rules/error-catch.d.ts +2 -0
- package/dist/analyze/rules/error-catch.js +14 -0
- package/dist/analyze/rules/escalation-catch.d.ts +2 -0
- package/dist/analyze/rules/escalation-catch.js +14 -0
- package/dist/analyze/rules/gateway-cardinality.d.ts +3 -0
- package/dist/analyze/rules/gateway-cardinality.js +17 -0
- package/dist/analyze/rules/index.d.ts +4 -0
- package/dist/analyze/rules/index.js +21 -0
- package/dist/analyze/rules/instantiating-gateway.d.ts +2 -0
- package/dist/analyze/rules/instantiating-gateway.js +14 -0
- package/dist/analyze/rules/non-interrupting-start.d.ts +2 -0
- package/dist/analyze/rules/non-interrupting-start.js +14 -0
- package/dist/analyze/rules/reachability.d.ts +2 -0
- package/dist/analyze/rules/reachability.js +25 -0
- package/dist/analyze/rules/rule.d.ts +7 -0
- package/dist/analyze/rules/rule.js +1 -0
- package/dist/analyze/rules/signal-catch.d.ts +2 -0
- package/dist/analyze/rules/signal-catch.js +12 -0
- package/dist/analyze/rules/split-join-pairing.d.ts +3 -0
- package/dist/analyze/rules/split-join-pairing.js +50 -0
- package/dist/analyze/rules/start-event.d.ts +2 -0
- package/dist/analyze/rules/start-event.js +8 -0
- package/dist/analyze/rules/task-message-flow.d.ts +2 -0
- package/dist/analyze/rules/task-message-flow.js +19 -0
- package/dist/analyze/scope-graph.d.ts +56 -0
- package/dist/analyze/scope-graph.js +89 -0
- package/dist/analyze-cli.d.ts +1 -0
- package/dist/analyze-cli.js +5 -0
- package/dist/analyze-run.d.ts +12 -0
- package/dist/analyze-run.js +85 -0
- package/dist/bpmn-ld-cli.d.ts +2 -0
- package/dist/bpmn-ld-cli.js +97 -0
- package/dist/build-cli.d.ts +1 -0
- package/dist/build-cli.js +2 -0
- package/dist/build.d.ts +3 -0
- package/dist/build.js +38 -0
- 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/dist/check-xml/check.d.ts +3 -0
- package/dist/check-xml/check.js +11 -0
- package/dist/check-xml/lint.d.ts +2 -0
- package/dist/check-xml/lint.js +47 -0
- package/dist/check-xml/moddle.d.ts +6 -0
- package/dist/check-xml/moddle.js +23 -0
- package/dist/check-xml/types.d.ts +20 -0
- package/dist/check-xml/types.js +1 -0
- package/dist/check-xml/xsd.d.ts +2 -0
- package/dist/check-xml/xsd.js +25 -0
- package/dist/check-xml-cli.d.ts +1 -0
- package/dist/check-xml-cli.js +5 -0
- package/dist/check-xml-run.d.ts +10 -0
- package/dist/check-xml-run.js +77 -0
- package/dist/convert/analyze-output.d.ts +3 -0
- package/dist/convert/analyze-output.js +8 -0
- package/dist/convert/convert.d.ts +19 -0
- package/dist/convert/convert.js +96 -0
- package/dist/convert/errors.d.ts +5 -0
- package/dist/convert/errors.js +8 -0
- package/dist/convert/extensions.d.ts +23 -0
- package/dist/convert/extensions.js +103 -0
- package/dist/convert/mapping-check.d.ts +15 -0
- package/dist/convert/mapping-check.js +66 -0
- package/dist/convert/mapping.d.ts +52 -0
- package/dist/convert/mapping.js +273 -0
- package/dist/convert/namespaces.d.ts +2 -0
- package/dist/convert/namespaces.js +19 -0
- package/dist/convert/validate-output.d.ts +2 -0
- package/dist/convert/validate-output.js +28 -0
- package/dist/convert/warnings.d.ts +9 -0
- package/dist/convert/warnings.js +67 -0
- package/dist/convert/xml-reader.d.ts +11 -0
- package/dist/convert/xml-reader.js +84 -0
- package/dist/convert-cli.d.ts +1 -0
- package/dist/convert-cli.js +5 -0
- package/dist/convert-run.d.ts +10 -0
- package/dist/convert-run.js +125 -0
- package/dist/coverage-cli.d.ts +1 -0
- package/dist/coverage-cli.js +8 -0
- package/dist/coverage-mappings.d.ts +3 -0
- package/dist/coverage-mappings.js +34 -0
- package/dist/coverage-scope.d.ts +11 -0
- package/dist/coverage-scope.js +187 -0
- package/dist/coverage-xsd.d.ts +15 -0
- package/dist/coverage-xsd.js +55 -0
- package/dist/coverage.d.ts +35 -0
- package/dist/coverage.js +152 -0
- package/dist/docs-cli.d.ts +1 -0
- package/dist/docs-cli.js +18 -0
- package/dist/docs.d.ts +8 -0
- package/dist/docs.js +136 -0
- package/dist/eval/checks.d.ts +19 -0
- package/dist/eval/checks.js +252 -0
- package/dist/eval/regenerate.d.ts +10 -0
- package/dist/eval/regenerate.js +48 -0
- package/dist/eval-regenerate-cli.d.ts +1 -0
- package/dist/eval-regenerate-cli.js +16 -0
- package/dist/export/data.d.ts +10 -0
- package/dist/export/data.js +127 -0
- package/dist/export/diagram.d.ts +8 -0
- package/dist/export/diagram.js +112 -0
- package/dist/export/element.d.ts +27 -0
- package/dist/export/element.js +175 -0
- package/dist/export/export.d.ts +22 -0
- package/dist/export/export.js +124 -0
- package/dist/export/extensions.d.ts +18 -0
- package/dist/export/extensions.js +122 -0
- package/dist/export/layout-export.d.ts +4 -0
- package/dist/export/layout-export.js +25 -0
- package/dist/export/mapping-check.d.ts +39 -0
- package/dist/export/mapping-check.js +175 -0
- package/dist/export/normalize.d.ts +3 -0
- package/dist/export/normalize.js +67 -0
- package/dist/export-cli.d.ts +1 -0
- package/dist/export-cli.js +5 -0
- package/dist/export-run.d.ts +10 -0
- package/dist/export-run.js +157 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +10 -0
- package/dist/install-skill-run.d.ts +8 -0
- package/dist/install-skill-run.js +30 -0
- package/dist/install-skill.d.ts +23 -0
- package/dist/install-skill.js +76 -0
- package/dist/layout/collaboration.d.ts +36 -0
- package/dist/layout/collaboration.js +152 -0
- package/dist/layout/di.d.ts +15 -0
- package/dist/layout/di.js +52 -0
- package/dist/layout/extract.d.ts +2 -0
- package/dist/layout/extract.js +99 -0
- package/dist/layout/lanes.d.ts +30 -0
- package/dist/layout/lanes.js +112 -0
- package/dist/layout/layering.d.ts +7 -0
- package/dist/layout/layering.js +53 -0
- package/dist/layout/layout.d.ts +12 -0
- package/dist/layout/layout.js +299 -0
- package/dist/layout/model.d.ts +52 -0
- package/dist/layout/model.js +10 -0
- package/dist/layout/placement.d.ts +25 -0
- package/dist/layout/placement.js +256 -0
- package/dist/layout/standalone.d.ts +8 -0
- package/dist/layout/standalone.js +50 -0
- package/dist/layout-cli.d.ts +1 -0
- package/dist/layout-cli.js +5 -0
- package/dist/layout-run.d.ts +9 -0
- package/dist/layout-run.js +105 -0
- package/dist/loader.d.ts +5 -0
- package/dist/loader.js +7 -0
- package/dist/namespace.d.ts +5 -0
- package/dist/namespace.js +5 -0
- package/dist/ontology.d.ts +19 -0
- package/dist/ontology.js +94 -0
- package/dist/paths.d.ts +1 -0
- package/dist/paths.js +2 -0
- package/dist/render/geometry.d.ts +40 -0
- package/dist/render/geometry.js +81 -0
- package/dist/render/renderer.d.ts +31 -0
- package/dist/render/renderer.js +369 -0
- package/dist/render/symbols.d.ts +10 -0
- package/dist/render/symbols.js +26 -0
- package/dist/render/text.d.ts +20 -0
- package/dist/render/text.js +28 -0
- package/dist/render-cli.d.ts +1 -0
- package/dist/render-cli.js +7 -0
- package/dist/render-run.d.ts +9 -0
- package/dist/render-run.js +161 -0
- package/dist/render.d.ts +4 -0
- package/dist/render.js +4 -0
- package/dist/schema-overrides.d.ts +14 -0
- package/dist/schema-overrides.js +36 -0
- package/dist/schema-validate.d.ts +5 -0
- package/dist/schema-validate.js +8 -0
- package/dist/schema.d.ts +6 -0
- package/dist/schema.js +114 -0
- package/dist/shacl.d.ts +15 -0
- package/dist/shacl.js +37 -0
- package/dist/validate-cli.d.ts +1 -0
- package/dist/validate-cli.js +5 -0
- package/dist/validate-run.d.ts +8 -0
- package/dist/validate-run.js +58 -0
- package/dist/validate.d.ts +11 -0
- package/dist/validate.js +94 -0
- package/dist/versioning-cli.d.ts +1 -0
- package/dist/versioning-cli.js +18 -0
- package/dist/versioning.d.ts +17 -0
- package/dist/versioning.js +45 -0
- package/ontology/core.ttl +993 -0
- package/ontology/di.ttl +167 -0
- package/package.json +77 -4
- 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/schema/bpmn-ld.schema.json +15230 -0
- package/shapes/core.shapes.ttl +398 -0
- package/skills/bpmn-ld/SKILL.md +154 -0
- package/skills/bpmn-ld/evals/models/order-approval-di.jsonld +296 -0
- package/skills/bpmn-ld/evals/models/refund-di.bpmn +82 -0
- package/skills/bpmn-ld/evals/models/refund.bpmn +18 -0
- package/skills/bpmn-ld/evals/outputs/explain-collaboration.md +22 -0
- package/skills/bpmn-ld/evals/outputs/explain-order-approval.md +24 -0
- package/skills/bpmn-ld/evals/outputs/explain-refund.md +17 -0
- package/skills/bpmn-ld/evals/outputs/generate-activity-compensation.jsonld +39 -0
- package/skills/bpmn-ld/evals/outputs/generate-ad-hoc-sub-process.jsonld +52 -0
- package/skills/bpmn-ld/evals/outputs/generate-boundary-event.jsonld +27 -0
- package/skills/bpmn-ld/evals/outputs/generate-collaboration.jsonld +49 -0
- package/skills/bpmn-ld/evals/outputs/generate-conditions.jsonld +93 -0
- package/skills/bpmn-ld/evals/outputs/generate-diagram-properties.jsonld +340 -0
- package/skills/bpmn-ld/evals/outputs/generate-error.jsonld +217 -0
- package/skills/bpmn-ld/evals/outputs/generate-escalation.jsonld +231 -0
- package/skills/bpmn-ld/evals/outputs/generate-event-definition-ref.jsonld +67 -0
- package/skills/bpmn-ld/evals/outputs/generate-event-sub-process.jsonld +54 -0
- package/skills/bpmn-ld/evals/outputs/generate-exclusive-choice.jsonld +32 -0
- package/skills/bpmn-ld/evals/outputs/generate-instantiating-gateway.jsonld +24 -0
- package/skills/bpmn-ld/evals/outputs/generate-lane-partition.jsonld +46 -0
- package/skills/bpmn-ld/evals/outputs/generate-link-event.expect.json +11 -0
- package/skills/bpmn-ld/evals/outputs/generate-link-event.jsonld +57 -0
- package/skills/bpmn-ld/evals/outputs/generate-loop.jsonld +30 -0
- package/skills/bpmn-ld/evals/outputs/generate-message.jsonld +61 -0
- package/skills/bpmn-ld/evals/outputs/generate-parallel-branches.jsonld +25 -0
- package/skills/bpmn-ld/evals/outputs/generate-process-attributes.jsonld +49 -0
- package/skills/bpmn-ld/evals/outputs/generate-script-task.jsonld +18 -0
- package/skills/bpmn-ld/evals/outputs/generate-signal.jsonld +178 -0
- package/skills/bpmn-ld/evals/outputs/generate-sub-process.jsonld +31 -0
- package/skills/bpmn-ld/evals/outputs/generate-targeted-compensation.jsonld +40 -0
- package/skills/bpmn-ld/evals/outputs/generate-task-implementation.jsonld +18 -0
- package/skills/bpmn-ld/evals/outputs/generate-task-message-references.jsonld +49 -0
- package/skills/bpmn-ld/evals/outputs/generate-transaction.jsonld +48 -0
- package/skills/bpmn-ld/evals/outputs/modify-order-approval.jsonld +376 -0
- package/skills/bpmn-ld/evals/outputs/modify-refund.jsonld +373 -0
- package/skills/bpmn-ld/evals/outputs/order-approval.jsonld +29 -0
- package/skills/bpmn-ld/evals/outputs/refine-order-approval.jsonld +377 -0
- package/skills/bpmn-ld/evals/prompts/explain-collaboration.md +3 -0
- package/skills/bpmn-ld/evals/prompts/explain-order-approval.md +3 -0
- package/skills/bpmn-ld/evals/prompts/explain-refund.md +3 -0
- package/skills/bpmn-ld/evals/prompts/generate-activity-compensation.md +1 -0
- package/skills/bpmn-ld/evals/prompts/generate-ad-hoc-sub-process.md +1 -0
- package/skills/bpmn-ld/evals/prompts/generate-boundary-event.md +1 -0
- package/skills/bpmn-ld/evals/prompts/generate-collaboration.md +1 -0
- package/skills/bpmn-ld/evals/prompts/generate-conditions.md +1 -0
- package/skills/bpmn-ld/evals/prompts/generate-diagram-properties.md +1 -0
- package/skills/bpmn-ld/evals/prompts/generate-error.md +1 -0
- package/skills/bpmn-ld/evals/prompts/generate-escalation.md +1 -0
- package/skills/bpmn-ld/evals/prompts/generate-event-definition-ref.md +1 -0
- package/skills/bpmn-ld/evals/prompts/generate-event-sub-process.md +1 -0
- package/skills/bpmn-ld/evals/prompts/generate-exclusive-choice.md +1 -0
- package/skills/bpmn-ld/evals/prompts/generate-instantiating-gateway.md +1 -0
- package/skills/bpmn-ld/evals/prompts/generate-lane-partition.md +1 -0
- package/skills/bpmn-ld/evals/prompts/generate-link-event.md +1 -0
- package/skills/bpmn-ld/evals/prompts/generate-loop.md +1 -0
- package/skills/bpmn-ld/evals/prompts/generate-message.md +1 -0
- package/skills/bpmn-ld/evals/prompts/generate-parallel-branches.md +1 -0
- package/skills/bpmn-ld/evals/prompts/generate-process-attributes.md +1 -0
- package/skills/bpmn-ld/evals/prompts/generate-script-task.md +1 -0
- package/skills/bpmn-ld/evals/prompts/generate-signal.md +1 -0
- package/skills/bpmn-ld/evals/prompts/generate-sub-process.md +1 -0
- package/skills/bpmn-ld/evals/prompts/generate-targeted-compensation.md +1 -0
- package/skills/bpmn-ld/evals/prompts/generate-task-implementation.md +1 -0
- package/skills/bpmn-ld/evals/prompts/generate-task-message-references.md +1 -0
- package/skills/bpmn-ld/evals/prompts/generate-transaction.md +1 -0
- package/skills/bpmn-ld/evals/prompts/modify-order-approval.md +4 -0
- package/skills/bpmn-ld/evals/prompts/modify-refund.md +4 -0
- package/skills/bpmn-ld/evals/prompts/order-approval.md +1 -0
- package/skills/bpmn-ld/evals/prompts/refine-order-approval.md +8 -0
- package/skills/bpmn-ld/examples/positive/activity-compensation.jsonld +39 -0
- package/skills/bpmn-ld/examples/positive/ad-hoc-sub-process.jsonld +52 -0
- package/skills/bpmn-ld/examples/positive/boundary-event.jsonld +27 -0
- package/skills/bpmn-ld/examples/positive/collaboration.jsonld +49 -0
- package/skills/bpmn-ld/examples/positive/conditions.jsonld +93 -0
- package/skills/bpmn-ld/examples/positive/diagram-properties.jsonld +340 -0
- package/skills/bpmn-ld/examples/positive/error.jsonld +208 -0
- package/skills/bpmn-ld/examples/positive/escalation.jsonld +231 -0
- package/skills/bpmn-ld/examples/positive/event-definition-ref.jsonld +142 -0
- package/skills/bpmn-ld/examples/positive/event-sub-process.jsonld +54 -0
- package/skills/bpmn-ld/examples/positive/exclusive-choice.jsonld +32 -0
- package/skills/bpmn-ld/examples/positive/instantiating-gateway.jsonld +24 -0
- package/skills/bpmn-ld/examples/positive/lane-partition.jsonld +46 -0
- package/skills/bpmn-ld/examples/positive/link-event.expect.json +10 -0
- package/skills/bpmn-ld/examples/positive/link-event.jsonld +138 -0
- package/skills/bpmn-ld/examples/positive/loop.jsonld +30 -0
- package/skills/bpmn-ld/examples/positive/message.jsonld +60 -0
- package/skills/bpmn-ld/examples/positive/order-approval.jsonld +29 -0
- package/skills/bpmn-ld/examples/positive/parallel-branches.jsonld +25 -0
- package/skills/bpmn-ld/examples/positive/process-attributes.jsonld +49 -0
- package/skills/bpmn-ld/examples/positive/script-task.jsonld +18 -0
- package/skills/bpmn-ld/examples/positive/signal.jsonld +150 -0
- package/skills/bpmn-ld/examples/positive/sub-process.jsonld +31 -0
- package/skills/bpmn-ld/examples/positive/targeted-compensation.jsonld +40 -0
- package/skills/bpmn-ld/examples/positive/task-implementation.jsonld +18 -0
- package/skills/bpmn-ld/examples/positive/task-message-references.jsonld +151 -0
- package/skills/bpmn-ld/examples/positive/transaction.jsonld +48 -0
- package/skills/bpmn-ld/references/clarification-and-refinement.md +60 -0
- package/skills/bpmn-ld/references/common-mistakes.md +110 -0
- package/skills/bpmn-ld/references/explain-and-document.md +36 -0
- package/skills/bpmn-ld/references/modify-existing-model.md +49 -0
- package/skills/bpmn-ld/references/patterns.md +292 -0
- package/skills/bpmn-ld/references/render-output.md +1 -0
- package/skills/bpmn-ld/references/rule-catalogue.md +183 -0
- package/skills/bpmn-ld/references/vocabulary-summary.md +65 -0
- package/skills/bpmn-ld/template.jsonld +14 -0
- package/templates/combined.jsonld +3 -0
- package/templates/core.jsonld +170 -0
- package/templates/core.shapes.ttl +398 -0
- package/templates/core.ttl +993 -0
- package/templates/di.jsonld +37 -0
- package/templates/di.ttl +167 -0
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
export const MODEL_NAMESPACE = "http://www.omg.org/spec/BPMN/20100524/MODEL";
|
|
2
|
+
export const DI_NAMESPACE = "http://www.omg.org/spec/BPMN/20100524/DI";
|
|
3
|
+
export const DC_NAMESPACE = "http://www.omg.org/spec/DD/20100524/DC";
|
|
4
|
+
export const DD_NAMESPACE = "http://www.omg.org/spec/DD/20100524/DI";
|
|
5
|
+
export const XSI_NAMESPACE = "http://www.w3.org/2001/XMLSchema-instance";
|
|
6
|
+
export const BPMN_NAMESPACES = [MODEL_NAMESPACE, DI_NAMESPACE, DC_NAMESPACE, DD_NAMESPACE];
|
|
7
|
+
export const REFERENCE_ATTRIBUTES = [
|
|
8
|
+
"sourceRef",
|
|
9
|
+
"targetRef",
|
|
10
|
+
"attachedToRef",
|
|
11
|
+
"processRef",
|
|
12
|
+
"default",
|
|
13
|
+
"errorRef",
|
|
14
|
+
"activityRef",
|
|
15
|
+
"escalationRef",
|
|
16
|
+
"messageRef",
|
|
17
|
+
"operationRef",
|
|
18
|
+
"itemRef",
|
|
19
|
+
"signalRef",
|
|
20
|
+
"structureRef",
|
|
21
|
+
"evaluatesToTypeRef",
|
|
22
|
+
"partitionElementRef",
|
|
23
|
+
"bpmnElement",
|
|
24
|
+
"sourceElement",
|
|
25
|
+
"targetElement",
|
|
26
|
+
];
|
|
27
|
+
export const REFERENCE_CHILDREN = ["flowNodeRef", "operationRef", "source", "target", "eventDefinitionRef"];
|
|
28
|
+
const named = { id: "id", name: "name" };
|
|
29
|
+
const withDefault = { ...named, default: "default" };
|
|
30
|
+
const implementedTasks = ["businessRuleTask", "userTask"];
|
|
31
|
+
const tasks = ["manualTask", "receiveTask", "scriptTask", "sendTask", "serviceTask", ...implementedTasks];
|
|
32
|
+
const withImplementation = { ...withDefault, implementation: "implementation" };
|
|
33
|
+
const gateways = ["exclusiveGateway", "parallelGateway", "inclusiveGateway", "eventBasedGateway", "complexGateway"];
|
|
34
|
+
const defaultableGateways = ["exclusiveGateway", "inclusiveGateway", "complexGateway"];
|
|
35
|
+
const events = ["startEvent", "endEvent", "intermediateCatchEvent", "intermediateThrowEvent", "implicitThrowEvent", "boundaryEvent"];
|
|
36
|
+
const definitions = [
|
|
37
|
+
"message",
|
|
38
|
+
"timer",
|
|
39
|
+
"error",
|
|
40
|
+
"signal",
|
|
41
|
+
"escalation",
|
|
42
|
+
"conditional",
|
|
43
|
+
"link",
|
|
44
|
+
"compensate",
|
|
45
|
+
"cancel",
|
|
46
|
+
"terminate",
|
|
47
|
+
].map((kind) => `${kind}EventDefinition`);
|
|
48
|
+
const capitalize = (name) => name[0].toUpperCase() + name.slice(1);
|
|
49
|
+
const typed = (names, attributes = named, type) => Object.fromEntries(names.map((name) => [name, { type: type ?? capitalize(name), attributes }]));
|
|
50
|
+
const expression = {
|
|
51
|
+
type: "FormalExpression",
|
|
52
|
+
attributes: { language: "language", evaluatesToTypeRef: "evaluatesToTypeRef" },
|
|
53
|
+
consumed: [`{${XSI_NAMESPACE}}type`],
|
|
54
|
+
bodyTerm: "body",
|
|
55
|
+
anonymous: true,
|
|
56
|
+
requiresBody: true,
|
|
57
|
+
};
|
|
58
|
+
const eventReferences = { eventDefinitionRef: "eventDefinitionRef" };
|
|
59
|
+
export const ELEMENT_MAPPINGS = {
|
|
60
|
+
process: {
|
|
61
|
+
type: "Process",
|
|
62
|
+
attributes: { ...named, isExecutable: "isExecutable", processType: "processType", isClosed: "isClosed" },
|
|
63
|
+
booleans: ["isExecutable", "isClosed"],
|
|
64
|
+
},
|
|
65
|
+
subProcess: {
|
|
66
|
+
type: "SubProcess",
|
|
67
|
+
attributes: { ...withDefault, triggeredByEvent: "triggeredByEvent" },
|
|
68
|
+
booleans: ["triggeredByEvent"],
|
|
69
|
+
},
|
|
70
|
+
adHocSubProcess: {
|
|
71
|
+
type: "AdHocSubProcess",
|
|
72
|
+
attributes: { ...withDefault, triggeredByEvent: "triggeredByEvent", ordering: "ordering", cancelRemainingInstances: "cancelRemainingInstances" },
|
|
73
|
+
booleans: ["triggeredByEvent", "cancelRemainingInstances"],
|
|
74
|
+
singles: { completionCondition: "completionCondition" },
|
|
75
|
+
},
|
|
76
|
+
transaction: {
|
|
77
|
+
type: "Transaction",
|
|
78
|
+
attributes: { ...withDefault, triggeredByEvent: "triggeredByEvent", method: "method" },
|
|
79
|
+
booleans: ["triggeredByEvent"],
|
|
80
|
+
hashPrefixed: ["method"],
|
|
81
|
+
},
|
|
82
|
+
...typed(["laneSet", "childLaneSet"], { id: "id" }, "LaneSet"),
|
|
83
|
+
lane: {
|
|
84
|
+
type: "Lane",
|
|
85
|
+
attributes: { ...named, partitionElementRef: "partitionElementRef" },
|
|
86
|
+
textLists: { flowNodeRef: "flowNodeRef" },
|
|
87
|
+
singles: { childLaneSet: "childLaneSet", partitionElement: "partitionElement" },
|
|
88
|
+
},
|
|
89
|
+
collaboration: { type: "Collaboration", attributes: { ...named, isClosed: "isClosed" }, booleans: ["isClosed"] },
|
|
90
|
+
participant: { type: "Participant", attributes: { ...named, processRef: "processRef" } },
|
|
91
|
+
association: {
|
|
92
|
+
type: "Association",
|
|
93
|
+
attributes: { ...named, sourceRef: "sourceRef", targetRef: "targetRef", associationDirection: "associationDirection" },
|
|
94
|
+
},
|
|
95
|
+
messageFlow: {
|
|
96
|
+
type: "MessageFlow",
|
|
97
|
+
attributes: { ...named, sourceRef: "sourceRef", targetRef: "targetRef", messageRef: "messageRef" },
|
|
98
|
+
},
|
|
99
|
+
message: { type: "Message", attributes: { ...named, itemRef: "itemRef" } },
|
|
100
|
+
signal: { type: "Signal", attributes: { ...named, structureRef: "structureRef" } },
|
|
101
|
+
error: { type: "Error", attributes: { ...named, errorCode: "errorCode", structureRef: "structureRef" } },
|
|
102
|
+
escalation: { type: "Escalation", attributes: { ...named, escalationCode: "escalationCode", structureRef: "structureRef" } },
|
|
103
|
+
task: { type: "ManualTask", attributes: withDefault },
|
|
104
|
+
...typed(["manualTask"], withDefault),
|
|
105
|
+
...typed(implementedTasks, withImplementation),
|
|
106
|
+
scriptTask: {
|
|
107
|
+
type: "ScriptTask",
|
|
108
|
+
attributes: { ...withDefault, scriptFormat: "scriptFormat" },
|
|
109
|
+
textChildren: { script: "script" },
|
|
110
|
+
},
|
|
111
|
+
serviceTask: { type: "ServiceTask", attributes: { ...withImplementation, operationRef: "operationRef" } },
|
|
112
|
+
sendTask: { type: "SendTask", attributes: { ...withImplementation, messageRef: "messageRef", operationRef: "operationRef" } },
|
|
113
|
+
receiveTask: {
|
|
114
|
+
type: "ReceiveTask",
|
|
115
|
+
attributes: { ...withImplementation, instantiate: "instantiate", messageRef: "messageRef", operationRef: "operationRef" },
|
|
116
|
+
booleans: ["instantiate"],
|
|
117
|
+
},
|
|
118
|
+
...typed(events),
|
|
119
|
+
startEvent: {
|
|
120
|
+
type: "StartEvent",
|
|
121
|
+
attributes: { ...named, isInterrupting: "isInterrupting", parallelMultiple: "parallelMultiple" },
|
|
122
|
+
booleans: ["isInterrupting", "parallelMultiple"],
|
|
123
|
+
},
|
|
124
|
+
intermediateCatchEvent: {
|
|
125
|
+
type: "IntermediateCatchEvent",
|
|
126
|
+
attributes: { ...named, parallelMultiple: "parallelMultiple" },
|
|
127
|
+
booleans: ["parallelMultiple"],
|
|
128
|
+
},
|
|
129
|
+
...typed(gateways, { ...named, gatewayDirection: "gatewayDirection" }),
|
|
130
|
+
eventBasedGateway: {
|
|
131
|
+
type: "EventBasedGateway",
|
|
132
|
+
attributes: { ...named, gatewayDirection: "gatewayDirection", instantiate: "instantiate", eventGatewayType: "eventGatewayType" },
|
|
133
|
+
booleans: ["instantiate"],
|
|
134
|
+
},
|
|
135
|
+
...typed(defaultableGateways, { ...named, gatewayDirection: "gatewayDirection", default: "default" }),
|
|
136
|
+
complexGateway: {
|
|
137
|
+
type: "ComplexGateway",
|
|
138
|
+
attributes: { ...named, gatewayDirection: "gatewayDirection", default: "default" },
|
|
139
|
+
singles: { activationCondition: "activationCondition" },
|
|
140
|
+
},
|
|
141
|
+
...typed(definitions),
|
|
142
|
+
conditionalEventDefinition: {
|
|
143
|
+
type: "ConditionalEventDefinition",
|
|
144
|
+
attributes: named,
|
|
145
|
+
singles: { condition: "condition" },
|
|
146
|
+
},
|
|
147
|
+
messageEventDefinition: {
|
|
148
|
+
type: "MessageEventDefinition",
|
|
149
|
+
attributes: { ...named, messageRef: "messageRef" },
|
|
150
|
+
textChildren: { operationRef: "operationRef" },
|
|
151
|
+
},
|
|
152
|
+
linkEventDefinition: {
|
|
153
|
+
type: "LinkEventDefinition",
|
|
154
|
+
attributes: named,
|
|
155
|
+
textLists: { source: "source" },
|
|
156
|
+
textChildren: { target: "target" },
|
|
157
|
+
},
|
|
158
|
+
signalEventDefinition: { type: "SignalEventDefinition", attributes: { ...named, signalRef: "signalRef" } },
|
|
159
|
+
boundaryEvent: {
|
|
160
|
+
type: "BoundaryEvent",
|
|
161
|
+
attributes: { ...named, attachedToRef: "attachedToRef", cancelActivity: "cancelActivity", parallelMultiple: "parallelMultiple" },
|
|
162
|
+
booleans: ["cancelActivity", "parallelMultiple"],
|
|
163
|
+
},
|
|
164
|
+
timerEventDefinition: {
|
|
165
|
+
type: "TimerEventDefinition",
|
|
166
|
+
attributes: named,
|
|
167
|
+
textChildren: { timeDate: "timeDate", timeDuration: "timeDuration", timeCycle: "timeCycle" },
|
|
168
|
+
},
|
|
169
|
+
errorEventDefinition: {
|
|
170
|
+
type: "ErrorEventDefinition",
|
|
171
|
+
attributes: { ...named, errorRef: "errorRef" },
|
|
172
|
+
lookups: [{ attribute: "errorRef", root: "error", from: "errorCode", term: "errorCode", exportOnly: true }],
|
|
173
|
+
},
|
|
174
|
+
escalationEventDefinition: {
|
|
175
|
+
type: "EscalationEventDefinition",
|
|
176
|
+
attributes: { ...named, escalationRef: "escalationRef" },
|
|
177
|
+
lookups: [{ attribute: "escalationRef", root: "escalation", from: "escalationCode", term: "escalationCode", exportOnly: true }],
|
|
178
|
+
},
|
|
179
|
+
compensateEventDefinition: {
|
|
180
|
+
type: "CompensateEventDefinition",
|
|
181
|
+
attributes: { ...named, waitForCompletion: "waitForCompletion", activityRef: "activityRef" },
|
|
182
|
+
booleans: ["waitForCompletion"],
|
|
183
|
+
},
|
|
184
|
+
sequenceFlow: {
|
|
185
|
+
type: "SequenceFlow",
|
|
186
|
+
attributes: { ...named, sourceRef: "sourceRef", targetRef: "targetRef", isImmediate: "isImmediate" },
|
|
187
|
+
booleans: ["isImmediate"],
|
|
188
|
+
singles: { conditionExpression: "conditionExpression" },
|
|
189
|
+
},
|
|
190
|
+
conditionExpression: expression,
|
|
191
|
+
completionCondition: expression,
|
|
192
|
+
condition: expression,
|
|
193
|
+
activationCondition: expression,
|
|
194
|
+
};
|
|
195
|
+
const diagramInterchange = {
|
|
196
|
+
BPMNDiagram: { type: "BPMNDiagram", attributes: { id: "id", name: "name", resolution: "resolution" }, numbers: ["resolution"], singles: { BPMNPlane: "plane" }, derivedChildIds: { plane: "Plane_" } },
|
|
197
|
+
BPMNPlane: { type: "BPMNPlane", attributes: { id: "id", bpmnElement: "bpmnElement" } },
|
|
198
|
+
BPMNShape: {
|
|
199
|
+
type: "BPMNShape",
|
|
200
|
+
attributes: { id: "id", bpmnElement: "bpmnElement", isExpanded: "isExpanded", isHorizontal: "isHorizontal", isMarkerVisible: "isMarkerVisible", isMessageVisible: "isMessageVisible" },
|
|
201
|
+
booleans: ["isExpanded", "isHorizontal", "isMarkerVisible", "isMessageVisible"],
|
|
202
|
+
singles: { Bounds: "bounds", BPMNLabel: "label" },
|
|
203
|
+
},
|
|
204
|
+
BPMNEdge: {
|
|
205
|
+
type: "BPMNEdge",
|
|
206
|
+
attributes: { id: "id", bpmnElement: "bpmnElement", sourceElement: "sourceElement", targetElement: "targetElement", messageVisibleKind: "messageVisibleKind" },
|
|
207
|
+
singles: { BPMNLabel: "label" },
|
|
208
|
+
},
|
|
209
|
+
BPMNLabel: { type: "BPMNLabel", attributes: {}, singles: { Bounds: "bounds" }, anonymous: true, requiresChild: "Bounds" },
|
|
210
|
+
Bounds: {
|
|
211
|
+
type: "Bounds",
|
|
212
|
+
attributes: { x: "x", y: "y", width: "width", height: "height" },
|
|
213
|
+
numbers: ["x", "y", "width", "height"],
|
|
214
|
+
},
|
|
215
|
+
waypoint: { type: "Point", attributes: { x: "x", y: "y" }, numbers: ["x", "y"] },
|
|
216
|
+
};
|
|
217
|
+
Object.assign(ELEMENT_MAPPINGS, diagramInterchange);
|
|
218
|
+
for (const name of events) {
|
|
219
|
+
const mapping = ELEMENT_MAPPINGS[name];
|
|
220
|
+
ELEMENT_MAPPINGS[name] = { ...mapping, textLists: { ...mapping.textLists, ...eventReferences } };
|
|
221
|
+
}
|
|
222
|
+
const activityAttributes = { isForCompensation: "isForCompensation", startQuantity: "startQuantity", completionQuantity: "completionQuantity" };
|
|
223
|
+
for (const name of [...tasks, "task", "subProcess", "adHocSubProcess", "transaction"]) {
|
|
224
|
+
const mapping = ELEMENT_MAPPINGS[name];
|
|
225
|
+
ELEMENT_MAPPINGS[name] = {
|
|
226
|
+
...mapping,
|
|
227
|
+
attributes: { ...mapping.attributes, ...activityAttributes },
|
|
228
|
+
booleans: [...(mapping.booleans ?? []), "isForCompensation"],
|
|
229
|
+
numbers: [...(mapping.numbers ?? []), "startQuantity", "completionQuantity"],
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
export const ELEMENT_NAMESPACES = {
|
|
233
|
+
BPMNDiagram: DI_NAMESPACE,
|
|
234
|
+
BPMNPlane: DI_NAMESPACE,
|
|
235
|
+
BPMNShape: DI_NAMESPACE,
|
|
236
|
+
BPMNEdge: DI_NAMESPACE,
|
|
237
|
+
BPMNLabel: DI_NAMESPACE,
|
|
238
|
+
Bounds: DC_NAMESPACE,
|
|
239
|
+
waypoint: DD_NAMESPACE,
|
|
240
|
+
};
|
|
241
|
+
export const isEmptyRequired = (element) => {
|
|
242
|
+
const mapping = ELEMENT_MAPPINGS[element.name];
|
|
243
|
+
return ((mapping?.requiresBody === true && element.text === "") ||
|
|
244
|
+
(mapping?.requiresChild !== undefined && !element.children.some((child) => child.name === mapping.requiresChild)));
|
|
245
|
+
};
|
|
246
|
+
const XSI_TYPE = `{${XSI_NAMESPACE}}type`;
|
|
247
|
+
export const concreteElement = (element) => {
|
|
248
|
+
const declared = element.name === "partitionElement" && element.namespace === MODEL_NAMESPACE ? element.attributes[XSI_TYPE] : undefined;
|
|
249
|
+
const local = declared?.slice(declared.indexOf(":") + 1);
|
|
250
|
+
const name = local !== undefined && /^t[A-Z]/.test(local) ? local[1].toLowerCase() + local.slice(2) : undefined;
|
|
251
|
+
return name !== undefined && name in ELEMENT_MAPPINGS && ELEMENT_NAMESPACES[name] === undefined ? { ...element, name } : element;
|
|
252
|
+
};
|
|
253
|
+
export const isMapped = (element) => element.namespace === (ELEMENT_NAMESPACES[element.name] ?? MODEL_NAMESPACE) && element.name in ELEMENT_MAPPINGS;
|
|
254
|
+
const eventContainment = Object.fromEntries(definitions.map((name) => [name, "eventDefinitions"]));
|
|
255
|
+
const container = {
|
|
256
|
+
...Object.fromEntries([...tasks, "task", ...events, ...gateways, "subProcess", "adHocSubProcess", "transaction", "sequenceFlow"].map((name) => [name, "flowElements"])),
|
|
257
|
+
laneSet: "laneSets",
|
|
258
|
+
association: "artifacts",
|
|
259
|
+
};
|
|
260
|
+
const planeContainment = { BPMNShape: "planeElements", BPMNEdge: "planeElements" };
|
|
261
|
+
export const CONTAINMENT = {
|
|
262
|
+
process: container,
|
|
263
|
+
subProcess: container,
|
|
264
|
+
adHocSubProcess: container,
|
|
265
|
+
transaction: container,
|
|
266
|
+
collaboration: { participant: "participants", messageFlow: "messageFlows" },
|
|
267
|
+
BPMNPlane: planeContainment,
|
|
268
|
+
BPMNEdge: { waypoint: "waypoints" },
|
|
269
|
+
laneSet: { lane: "lanes" },
|
|
270
|
+
childLaneSet: { lane: "lanes" },
|
|
271
|
+
...Object.fromEntries(events.map((event) => [event, eventContainment])),
|
|
272
|
+
};
|
|
273
|
+
export const ROOT_ELEMENTS = ["message", "signal", "error", "escalation", ...definitions, "collaboration", "process", "BPMNDiagram"];
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { ConversionError } from "./errors.js";
|
|
2
|
+
import { BPMN_NAMESPACES } from "./mapping.js";
|
|
3
|
+
const BPMN_FAMILY = /^https?:\/\/(?:www\.|schema\.)?omg\.org\/(?:spec\/(?:BPMN|DD)\/\d|bpmn)/i;
|
|
4
|
+
const ATTRIBUTE_NAMESPACE = /^\{(.*)\}(.*)$/;
|
|
5
|
+
const isUnrecognisedBpmn = (namespace) => BPMN_FAMILY.test(namespace) && !BPMN_NAMESPACES.includes(namespace);
|
|
6
|
+
const reject = (namespace, construct, location) => {
|
|
7
|
+
throw new ConversionError("unrecognised-bpmn-namespace", `unrecognised BPMN namespace ${namespace} on ${construct} at ${location}; supported namespaces are ${BPMN_NAMESPACES.join(", ")}`);
|
|
8
|
+
};
|
|
9
|
+
export const assertSupportedNamespaces = (element) => {
|
|
10
|
+
if (isUnrecognisedBpmn(element.namespace))
|
|
11
|
+
reject(element.namespace, element.name, element.location);
|
|
12
|
+
for (const key of Object.keys(element.attributes)) {
|
|
13
|
+
const match = ATTRIBUTE_NAMESPACE.exec(key);
|
|
14
|
+
if (match && isUnrecognisedBpmn(match[1]))
|
|
15
|
+
reject(match[1], `${element.name}@${match[2]}`, `${element.location}/@${match[2]}`);
|
|
16
|
+
}
|
|
17
|
+
for (const child of element.children)
|
|
18
|
+
assertSupportedNamespaces(child);
|
|
19
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { tmpdir } from "node:os";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { ROOT } from "../paths.js";
|
|
5
|
+
import { compileSchema, validateWithSchema } from "../schema-validate.js";
|
|
6
|
+
import { validateShacl } from "../shacl.js";
|
|
7
|
+
import { validateExample } from "../validate.js";
|
|
8
|
+
export const validateConverted = async (document) => {
|
|
9
|
+
const errors = validateWithSchema(document, compileSchema()).map((e) => `schema: ${e}`);
|
|
10
|
+
const local = { ...document, "@context": [join(ROOT, "contexts/combined.jsonld"), document["@context"][1]] };
|
|
11
|
+
const directory = mkdtempSync(join(tmpdir(), "convert-"));
|
|
12
|
+
try {
|
|
13
|
+
const file = join(directory, "out.jsonld");
|
|
14
|
+
writeFileSync(file, JSON.stringify(local));
|
|
15
|
+
const structural = await validateExample(file);
|
|
16
|
+
errors.push(...structural.errors);
|
|
17
|
+
if (structural.valid) {
|
|
18
|
+
const shacl = await validateShacl(file);
|
|
19
|
+
shacl.violations.forEach((v) => errors.push(`shacl: ${v.focusNode} violates ${v.sourceShape}`));
|
|
20
|
+
if (!shacl.conforms && shacl.violations.length === 0)
|
|
21
|
+
errors.push("shacl: validation failed");
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
finally {
|
|
25
|
+
rmSync(directory, { recursive: true, force: true });
|
|
26
|
+
}
|
|
27
|
+
return errors;
|
|
28
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type XmlElement } from "./xml-reader.ts";
|
|
2
|
+
export type WarningKind = "foreign-namespace" | "unsupported" | "dangling-reference";
|
|
3
|
+
export interface Warning {
|
|
4
|
+
kind: WarningKind;
|
|
5
|
+
construct: string;
|
|
6
|
+
location: string;
|
|
7
|
+
message?: string;
|
|
8
|
+
}
|
|
9
|
+
export declare const collectWarnings: (root: XmlElement) => Warning[];
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { BPMN_NAMESPACES, CONTAINMENT, concreteElement, ELEMENT_MAPPINGS, isEmptyRequired, isMapped, MODEL_NAMESPACE, REFERENCE_ATTRIBUTES, REFERENCE_CHILDREN, ROOT_ELEMENTS, XSI_NAMESPACE, } from "./mapping.js";
|
|
2
|
+
import { extensionWarnings, isExtensionAttribute } from "./extensions.js";
|
|
3
|
+
import { collectIds } from "./xml-reader.js";
|
|
4
|
+
const ATTRIBUTE_NAMESPACE = /^\{(.*)\}(.*)$/;
|
|
5
|
+
const XML_NAMESPACES = [XSI_NAMESPACE, "xml", "http://www.w3.org/XML/1998/namespace"];
|
|
6
|
+
const mappedAttributes = (element) => {
|
|
7
|
+
const mapping = isMapped(element) ? ELEMENT_MAPPINGS[element.name] : undefined;
|
|
8
|
+
return new Set([...Object.keys(mapping?.attributes ?? {}), ...(mapping?.consumed ?? []), ...(mapping?.lookups ?? []).map((lookup) => lookup.attribute)]);
|
|
9
|
+
};
|
|
10
|
+
const consumedRoots = new Set(Object.values(ELEMENT_MAPPINGS).flatMap((mapping) => (mapping.lookups ?? []).map((lookup) => lookup.root)));
|
|
11
|
+
const isHandledChild = (parent, child) => {
|
|
12
|
+
if (parent.name === "definitions")
|
|
13
|
+
return (isMapped(child) && ROOT_ELEMENTS.includes(child.name)) || (child.namespace === MODEL_NAMESPACE && consumedRoots.has(child.name));
|
|
14
|
+
const mapping = ELEMENT_MAPPINGS[parent.name];
|
|
15
|
+
if (child.namespace === MODEL_NAMESPACE && child.name === "extensionElements")
|
|
16
|
+
return true;
|
|
17
|
+
if (child.namespace === MODEL_NAMESPACE && (child.name in (mapping.textChildren ?? {}) || child.name in (mapping.textLists ?? {})))
|
|
18
|
+
return true;
|
|
19
|
+
return isMapped(concreteElement(child)) && (child.name in (mapping.singles ?? {}) || child.name in (CONTAINMENT[parent.name] ?? {}));
|
|
20
|
+
};
|
|
21
|
+
const attributeWarnings = (element, ids) => {
|
|
22
|
+
const allowed = mappedAttributes(element);
|
|
23
|
+
return Object.keys(element.attributes).flatMap((key) => {
|
|
24
|
+
if (allowed.has(key)) {
|
|
25
|
+
const dangling = REFERENCE_ATTRIBUTES.includes(key) && !ids.has(element.attributes[key]);
|
|
26
|
+
return dangling ? [{ kind: "dangling-reference", construct: `${element.name}@${key}`, location: `${element.location}/@${key}` }] : [];
|
|
27
|
+
}
|
|
28
|
+
if (isMapped(element) && isExtensionAttribute(key))
|
|
29
|
+
return [];
|
|
30
|
+
const foreign = ATTRIBUTE_NAMESPACE.exec(key);
|
|
31
|
+
if (foreign && XML_NAMESPACES.includes(foreign[1]))
|
|
32
|
+
return [];
|
|
33
|
+
const location = `${element.location}/@${foreign ? foreign[2] : key}`;
|
|
34
|
+
if (foreign)
|
|
35
|
+
return [{ kind: "foreign-namespace", construct: `${element.name}@${foreign[2]}`, location }];
|
|
36
|
+
return [{ kind: "unsupported", construct: `${element.name}@${key}`, location }];
|
|
37
|
+
});
|
|
38
|
+
};
|
|
39
|
+
const dropped = (element) => element.name === "extensionElements" && element.namespace === MODEL_NAMESPACE
|
|
40
|
+
? element.children.map((child) => ({ kind: "foreign-namespace", construct: child.name, location: child.location }))
|
|
41
|
+
: [
|
|
42
|
+
{
|
|
43
|
+
kind: BPMN_NAMESPACES.includes(element.namespace) ? "unsupported" : "foreign-namespace",
|
|
44
|
+
construct: element.name,
|
|
45
|
+
location: element.location,
|
|
46
|
+
},
|
|
47
|
+
];
|
|
48
|
+
const childWarnings = (parent, child, ids) => {
|
|
49
|
+
if (!isHandledChild(parent, child))
|
|
50
|
+
return dropped(child);
|
|
51
|
+
if (isMapped(concreteElement(child)))
|
|
52
|
+
return walk(concreteElement(child), ids);
|
|
53
|
+
if (child.name === "extensionElements")
|
|
54
|
+
return extensionWarnings(child);
|
|
55
|
+
const dangling = REFERENCE_CHILDREN.includes(child.name) && !ids.has(child.text);
|
|
56
|
+
return dangling ? [{ kind: "dangling-reference", construct: child.name, location: child.location }] : [];
|
|
57
|
+
};
|
|
58
|
+
const lossyWarnings = (element) => {
|
|
59
|
+
const lossy = isMapped(element) && (element.name === "task" || isEmptyRequired(element));
|
|
60
|
+
return lossy ? [{ kind: "unsupported", construct: element.name, location: element.location }] : [];
|
|
61
|
+
};
|
|
62
|
+
const walk = (element, ids) => [
|
|
63
|
+
...lossyWarnings(element),
|
|
64
|
+
...attributeWarnings(element, ids),
|
|
65
|
+
...element.children.flatMap((child) => childWarnings(element, child, ids)),
|
|
66
|
+
];
|
|
67
|
+
export const collectWarnings = (root) => walk(root, collectIds(root));
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface XmlElement {
|
|
2
|
+
namespace: string;
|
|
3
|
+
name: string;
|
|
4
|
+
attributes: Record<string, string>;
|
|
5
|
+
declarations: [string, string][];
|
|
6
|
+
children: XmlElement[];
|
|
7
|
+
text: string;
|
|
8
|
+
location: string;
|
|
9
|
+
}
|
|
10
|
+
export declare const readXml: (xml: string) => XmlElement;
|
|
11
|
+
export declare const collectIds: (element: XmlElement, ids?: Set<string>) => Set<string>;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { XMLParser } from "fast-xml-parser";
|
|
2
|
+
import { ConversionError } from "./errors.js";
|
|
3
|
+
const XMLNS = "xmlns";
|
|
4
|
+
const parser = new XMLParser({
|
|
5
|
+
preserveOrder: true,
|
|
6
|
+
ignoreAttributes: false,
|
|
7
|
+
attributeNamePrefix: "@_",
|
|
8
|
+
attributesGroupName: ":@",
|
|
9
|
+
trimValues: true,
|
|
10
|
+
parseTagValue: false,
|
|
11
|
+
parseAttributeValue: false,
|
|
12
|
+
htmlEntities: true,
|
|
13
|
+
});
|
|
14
|
+
const splitName = (qualified) => {
|
|
15
|
+
const index = qualified.indexOf(":");
|
|
16
|
+
return index < 0 ? ["", qualified] : [qualified.slice(0, index), qualified.slice(index + 1)];
|
|
17
|
+
};
|
|
18
|
+
const tagOf = (node) => Object.keys(node).find((key) => key !== ":@" && key !== "#text");
|
|
19
|
+
const resolve = (nodes, scope, parent) => {
|
|
20
|
+
const seen = new Map();
|
|
21
|
+
return nodes.flatMap((node) => {
|
|
22
|
+
const tag = tagOf(node);
|
|
23
|
+
if (tag === undefined)
|
|
24
|
+
return [];
|
|
25
|
+
const raw = (node[":@"] ?? {});
|
|
26
|
+
const local = new Map(scope);
|
|
27
|
+
const declarations = [];
|
|
28
|
+
for (const [key, value] of Object.entries(raw)) {
|
|
29
|
+
const name = key.slice(2);
|
|
30
|
+
const declared = name === XMLNS ? "" : name.startsWith(`${XMLNS}:`) ? name.slice(XMLNS.length + 1) : undefined;
|
|
31
|
+
if (declared === undefined)
|
|
32
|
+
continue;
|
|
33
|
+
local.set(declared, value);
|
|
34
|
+
declarations.push([declared, value]);
|
|
35
|
+
}
|
|
36
|
+
const attributes = {};
|
|
37
|
+
for (const [key, value] of Object.entries(raw)) {
|
|
38
|
+
const name = key.slice(2);
|
|
39
|
+
if (name === XMLNS || name.startsWith(`${XMLNS}:`))
|
|
40
|
+
continue;
|
|
41
|
+
const [prefix, localName] = splitName(name);
|
|
42
|
+
attributes[prefix ? `{${local.get(prefix) ?? prefix}}${localName}` : localName] = value;
|
|
43
|
+
}
|
|
44
|
+
const content = node[tag];
|
|
45
|
+
const [prefix, name] = splitName(tag);
|
|
46
|
+
const index = (seen.get(name) ?? 0) + 1;
|
|
47
|
+
seen.set(name, index);
|
|
48
|
+
const location = parent === null ? `/${name}` : `${parent}/${name}[${index}]`;
|
|
49
|
+
return [
|
|
50
|
+
{
|
|
51
|
+
namespace: local.get(prefix) ?? "",
|
|
52
|
+
name,
|
|
53
|
+
attributes,
|
|
54
|
+
declarations,
|
|
55
|
+
children: resolve(content, local, location),
|
|
56
|
+
text: content
|
|
57
|
+
.filter((child) => "#text" in child)
|
|
58
|
+
.map((child) => String(child["#text"]))
|
|
59
|
+
.join(""),
|
|
60
|
+
location,
|
|
61
|
+
},
|
|
62
|
+
];
|
|
63
|
+
});
|
|
64
|
+
};
|
|
65
|
+
export const readXml = (xml) => {
|
|
66
|
+
let parsed;
|
|
67
|
+
try {
|
|
68
|
+
parsed = parser.parse(xml, true);
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
throw new ConversionError("malformed-xml", `input is not well-formed XML: ${error instanceof Error ? error.message : String(error)}`);
|
|
72
|
+
}
|
|
73
|
+
const [root] = resolve(parsed.filter((node) => !("?xml" in node)), new Map(), null);
|
|
74
|
+
if (!root)
|
|
75
|
+
throw new ConversionError("malformed-xml", "input is not well-formed XML: no root element");
|
|
76
|
+
return root;
|
|
77
|
+
};
|
|
78
|
+
export const collectIds = (element, ids = new Set()) => {
|
|
79
|
+
if (element.attributes.id !== undefined)
|
|
80
|
+
ids.add(element.attributes.id);
|
|
81
|
+
for (const child of element.children)
|
|
82
|
+
collectIds(child, ids);
|
|
83
|
+
return ids;
|
|
84
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare const EXIT_OK = 0;
|
|
2
|
+
export declare const EXIT_CHECK_FAILED = 1;
|
|
3
|
+
export declare const EXIT_USAGE = 2;
|
|
4
|
+
export interface CliResult {
|
|
5
|
+
exitCode: number;
|
|
6
|
+
stdout: string;
|
|
7
|
+
stderr: string;
|
|
8
|
+
}
|
|
9
|
+
export declare const USAGE = "Usage: convert <input.bpmn> [options]\n\nConverts a BPMN 2.0 XML file to BPMN-LD JSON-LD.\n\nOptions:\n -o, --output <file> Write JSON-LD to <file> instead of standard output\n --base <iri> Document base IRI (default: derived from the input file name)\n --strict Exit with code 1 if the conversion produced any warning\n --validate Validate the output against the JSON Schema and SHACL shapes\n -h, --help Show this help\n\nWarnings and errors are written to standard error.\n\nExit codes:\n 0 Converted successfully\n 1 Strict mode found warnings, or validation failed\n 2 Usage error or unusable input (missing file, malformed XML, not BPMN)\n";
|
|
10
|
+
export declare const runConvert: (argv: string[]) => Promise<CliResult>;
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { convert } from "./convert/convert.js";
|
|
3
|
+
import { ConversionError } from "./convert/errors.js";
|
|
4
|
+
import { validateConverted } from "./convert/validate-output.js";
|
|
5
|
+
export const EXIT_OK = 0;
|
|
6
|
+
export const EXIT_CHECK_FAILED = 1;
|
|
7
|
+
export const EXIT_USAGE = 2;
|
|
8
|
+
export const USAGE = `Usage: convert <input.bpmn> [options]
|
|
9
|
+
|
|
10
|
+
Converts a BPMN 2.0 XML file to BPMN-LD JSON-LD.
|
|
11
|
+
|
|
12
|
+
Options:
|
|
13
|
+
-o, --output <file> Write JSON-LD to <file> instead of standard output
|
|
14
|
+
--base <iri> Document base IRI (default: derived from the input file name)
|
|
15
|
+
--strict Exit with code 1 if the conversion produced any warning
|
|
16
|
+
--validate Validate the output against the JSON Schema and SHACL shapes
|
|
17
|
+
-h, --help Show this help
|
|
18
|
+
|
|
19
|
+
Warnings and errors are written to standard error.
|
|
20
|
+
|
|
21
|
+
Exit codes:
|
|
22
|
+
0 Converted successfully
|
|
23
|
+
1 Strict mode found warnings, or validation failed
|
|
24
|
+
2 Usage error or unusable input (missing file, malformed XML, not BPMN)
|
|
25
|
+
`;
|
|
26
|
+
class UsageError extends Error {
|
|
27
|
+
}
|
|
28
|
+
const parseArgs = (argv) => {
|
|
29
|
+
const options = { input: "", strict: false, validate: false };
|
|
30
|
+
let input;
|
|
31
|
+
const valueOf = (flag, index) => {
|
|
32
|
+
const value = argv[index];
|
|
33
|
+
if (value === undefined || value.startsWith("-"))
|
|
34
|
+
throw new UsageError(`${flag} requires a value`);
|
|
35
|
+
return value;
|
|
36
|
+
};
|
|
37
|
+
for (let i = 0; i < argv.length; i++) {
|
|
38
|
+
const arg = argv[i];
|
|
39
|
+
if (arg === "-h" || arg === "--help")
|
|
40
|
+
return "help";
|
|
41
|
+
else if (arg === "-o" || arg === "--output")
|
|
42
|
+
options.output = valueOf(arg, ++i);
|
|
43
|
+
else if (arg === "--base")
|
|
44
|
+
options.base = valueOf(arg, ++i);
|
|
45
|
+
else if (arg === "--strict")
|
|
46
|
+
options.strict = true;
|
|
47
|
+
else if (arg === "--validate")
|
|
48
|
+
options.validate = true;
|
|
49
|
+
else if (arg.startsWith("-"))
|
|
50
|
+
throw new UsageError(`unknown option ${arg}`);
|
|
51
|
+
else if (input !== undefined)
|
|
52
|
+
throw new UsageError(`unexpected extra argument ${arg}`);
|
|
53
|
+
else
|
|
54
|
+
input = arg;
|
|
55
|
+
}
|
|
56
|
+
if (input === undefined)
|
|
57
|
+
throw new UsageError("missing input file");
|
|
58
|
+
options.input = input;
|
|
59
|
+
return options;
|
|
60
|
+
};
|
|
61
|
+
const usageFailure = (message) => ({ exitCode: EXIT_USAGE, stdout: "", stderr: `error: ${message}\n\n${USAGE}` });
|
|
62
|
+
const readInput = (path) => {
|
|
63
|
+
try {
|
|
64
|
+
return readFileSync(path, "utf8");
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
const reason = error.code === "ENOENT" ? "no such file" : (error.message ?? "cannot read");
|
|
68
|
+
throw new UsageError(`cannot read ${path}: ${reason}`);
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
export const runConvert = async (argv) => {
|
|
72
|
+
let options;
|
|
73
|
+
try {
|
|
74
|
+
options = parseArgs(argv);
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
if (error instanceof UsageError)
|
|
78
|
+
return usageFailure(error.message);
|
|
79
|
+
throw error;
|
|
80
|
+
}
|
|
81
|
+
if (options === "help")
|
|
82
|
+
return { exitCode: EXIT_OK, stdout: USAGE, stderr: "" };
|
|
83
|
+
let xml;
|
|
84
|
+
try {
|
|
85
|
+
xml = readInput(options.input);
|
|
86
|
+
}
|
|
87
|
+
catch (error) {
|
|
88
|
+
return { exitCode: EXIT_USAGE, stdout: "", stderr: `error: ${error.message}\n` };
|
|
89
|
+
}
|
|
90
|
+
let result;
|
|
91
|
+
try {
|
|
92
|
+
result = convert(xml, { base: options.base, fileName: options.input });
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
if (error instanceof ConversionError)
|
|
96
|
+
return { exitCode: EXIT_USAGE, stdout: "", stderr: `error: ${options.input}: ${error.message} (${error.code})\n` };
|
|
97
|
+
throw error;
|
|
98
|
+
}
|
|
99
|
+
const lines = result.warnings.map((w) => `warning: ${w.kind} ${w.construct} at ${w.location}${w.message ? `: ${w.message}` : ""}`);
|
|
100
|
+
let exitCode = EXIT_OK;
|
|
101
|
+
if (options.strict && result.warnings.length > 0) {
|
|
102
|
+
lines.push(`error: strict mode: ${result.warnings.length} warning(s)`);
|
|
103
|
+
exitCode = EXIT_CHECK_FAILED;
|
|
104
|
+
}
|
|
105
|
+
if (options.validate) {
|
|
106
|
+
const errors = await validateConverted(result.document);
|
|
107
|
+
if (errors.length > 0) {
|
|
108
|
+
lines.push(...errors.map((e) => `error: validation: ${e}`));
|
|
109
|
+
exitCode = EXIT_CHECK_FAILED;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
const json = `${JSON.stringify(result.document, null, 2)}\n`;
|
|
113
|
+
let stdout = "";
|
|
114
|
+
if (options.output === undefined)
|
|
115
|
+
stdout = json;
|
|
116
|
+
else {
|
|
117
|
+
try {
|
|
118
|
+
writeFileSync(options.output, json);
|
|
119
|
+
}
|
|
120
|
+
catch (error) {
|
|
121
|
+
return { exitCode: EXIT_USAGE, stdout: "", stderr: [...lines, `error: cannot write ${options.output}: ${error.message}`].join("\n") + "\n" };
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return { exitCode, stdout, stderr: lines.length ? `${lines.join("\n")}\n` : "" };
|
|
125
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|