@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,8 @@
|
|
|
1
|
+
import { ROOT } from "./paths.js";
|
|
2
|
+
import { writeReports } from "./coverage.js";
|
|
3
|
+
const { summary, unclassified } = writeReports(ROOT);
|
|
4
|
+
console.log(`coverage: ${summary.total.covered} covered, ${summary.total.gap} gaps, ${summary.total["out-of-scope"]} out of scope`);
|
|
5
|
+
if (unclassified.length) {
|
|
6
|
+
console.error(`unclassified XSD types: ${unclassified.join(", ")}`);
|
|
7
|
+
process.exitCode = 1;
|
|
8
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export const BUILT_IN_PROPERTIES = {
|
|
2
|
+
id: "@id",
|
|
3
|
+
};
|
|
4
|
+
export const CLASS_ALIASES = {
|
|
5
|
+
Diagram: "BPMNDiagram",
|
|
6
|
+
Plane: "BPMNPlane",
|
|
7
|
+
Node: "DiagramElement",
|
|
8
|
+
Shape: "BPMNShape",
|
|
9
|
+
LabeledShape: "BPMNShape",
|
|
10
|
+
Edge: "BPMNEdge",
|
|
11
|
+
LabeledEdge: "BPMNEdge",
|
|
12
|
+
Label: "BPMNLabel",
|
|
13
|
+
};
|
|
14
|
+
export const PROPERTY_ALIASES = {
|
|
15
|
+
flowElement: "flowElements",
|
|
16
|
+
laneSet: "laneSets",
|
|
17
|
+
artifact: "artifacts",
|
|
18
|
+
lane: "lanes",
|
|
19
|
+
eventDefinition: "eventDefinitions",
|
|
20
|
+
participant: "participants",
|
|
21
|
+
messageFlow: "messageFlows",
|
|
22
|
+
dataInput: "dataInputs",
|
|
23
|
+
dataOutput: "dataOutputs",
|
|
24
|
+
inputSet: "inputSets",
|
|
25
|
+
outputSet: "outputSets",
|
|
26
|
+
dataInputAssociation: "dataInputAssociations",
|
|
27
|
+
dataOutputAssociation: "dataOutputAssociations",
|
|
28
|
+
assignment: "assignments",
|
|
29
|
+
waypoint: "waypoints",
|
|
30
|
+
BPMNPlane: "plane",
|
|
31
|
+
BPMNLabel: "label",
|
|
32
|
+
Bounds: "bounds",
|
|
33
|
+
"Plane.DiagramElement": "planeElements",
|
|
34
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export type CoverageScope = {
|
|
2
|
+
inScope: string[];
|
|
3
|
+
outOfScopeTypes: Record<string, string[]>;
|
|
4
|
+
outOfScopeProperties: Record<string, string[]>;
|
|
5
|
+
outOfScopeReasons?: Record<string, string>;
|
|
6
|
+
};
|
|
7
|
+
export declare const IN_SCOPE_TYPES: string[];
|
|
8
|
+
export declare const OUT_OF_SCOPE_TYPES: Record<string, string[]>;
|
|
9
|
+
export declare const OUT_OF_SCOPE_PROPERTIES: Record<string, string[]>;
|
|
10
|
+
export declare const OUT_OF_SCOPE_REASONS: Record<string, string>;
|
|
11
|
+
export declare const REAL_SCOPE: CoverageScope;
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
export const IN_SCOPE_TYPES = [
|
|
2
|
+
"tBaseElement",
|
|
3
|
+
"tRootElement",
|
|
4
|
+
"tFlowElement",
|
|
5
|
+
"tFlowNode",
|
|
6
|
+
"tProcess",
|
|
7
|
+
"tSubProcess",
|
|
8
|
+
"tAdHocSubProcess",
|
|
9
|
+
"tTransaction",
|
|
10
|
+
"tActivity",
|
|
11
|
+
"tTask",
|
|
12
|
+
"tUserTask",
|
|
13
|
+
"tServiceTask",
|
|
14
|
+
"tScriptTask",
|
|
15
|
+
"tSendTask",
|
|
16
|
+
"tReceiveTask",
|
|
17
|
+
"tManualTask",
|
|
18
|
+
"tBusinessRuleTask",
|
|
19
|
+
"tGateway",
|
|
20
|
+
"tExclusiveGateway",
|
|
21
|
+
"tParallelGateway",
|
|
22
|
+
"tInclusiveGateway",
|
|
23
|
+
"tEventBasedGateway",
|
|
24
|
+
"tComplexGateway",
|
|
25
|
+
"tSequenceFlow",
|
|
26
|
+
"tArtifact",
|
|
27
|
+
"tAssociation",
|
|
28
|
+
"tEvent",
|
|
29
|
+
"tCatchEvent",
|
|
30
|
+
"tThrowEvent",
|
|
31
|
+
"tStartEvent",
|
|
32
|
+
"tEndEvent",
|
|
33
|
+
"tIntermediateCatchEvent",
|
|
34
|
+
"tIntermediateThrowEvent",
|
|
35
|
+
"tBoundaryEvent",
|
|
36
|
+
"tImplicitThrowEvent",
|
|
37
|
+
"tEventDefinition",
|
|
38
|
+
"tMessageEventDefinition",
|
|
39
|
+
"tTimerEventDefinition",
|
|
40
|
+
"tErrorEventDefinition",
|
|
41
|
+
"tSignalEventDefinition",
|
|
42
|
+
"tEscalationEventDefinition",
|
|
43
|
+
"tConditionalEventDefinition",
|
|
44
|
+
"tLinkEventDefinition",
|
|
45
|
+
"tCompensateEventDefinition",
|
|
46
|
+
"tCancelEventDefinition",
|
|
47
|
+
"tTerminateEventDefinition",
|
|
48
|
+
"tMessage",
|
|
49
|
+
"tSignal",
|
|
50
|
+
"tError",
|
|
51
|
+
"tEscalation",
|
|
52
|
+
"tExpression",
|
|
53
|
+
"tFormalExpression",
|
|
54
|
+
"tLaneSet",
|
|
55
|
+
"tLane",
|
|
56
|
+
"tCollaboration",
|
|
57
|
+
"tParticipant",
|
|
58
|
+
"tMessageFlow",
|
|
59
|
+
"tAssignment",
|
|
60
|
+
"tDataAssociation",
|
|
61
|
+
"tDataInput",
|
|
62
|
+
"tDataInputAssociation",
|
|
63
|
+
"tDataObject",
|
|
64
|
+
"tDataObjectReference",
|
|
65
|
+
"tDataOutput",
|
|
66
|
+
"tDataOutputAssociation",
|
|
67
|
+
"tDataStore",
|
|
68
|
+
"tDataStoreReference",
|
|
69
|
+
"tInputOutputSpecification",
|
|
70
|
+
"tInputSet",
|
|
71
|
+
"tOutputSet",
|
|
72
|
+
"BPMNDiagram",
|
|
73
|
+
"BPMNPlane",
|
|
74
|
+
"BPMNShape",
|
|
75
|
+
"BPMNEdge",
|
|
76
|
+
"BPMNLabel",
|
|
77
|
+
"Bounds",
|
|
78
|
+
"Point",
|
|
79
|
+
"DiagramElement",
|
|
80
|
+
"Diagram",
|
|
81
|
+
"Node",
|
|
82
|
+
"Edge",
|
|
83
|
+
"LabeledEdge",
|
|
84
|
+
"Shape",
|
|
85
|
+
"LabeledShape",
|
|
86
|
+
"Label",
|
|
87
|
+
"Plane",
|
|
88
|
+
];
|
|
89
|
+
export const OUT_OF_SCOPE_TYPES = {
|
|
90
|
+
data: [
|
|
91
|
+
"tDataState",
|
|
92
|
+
"tInputOutputBinding",
|
|
93
|
+
"tItemDefinition",
|
|
94
|
+
"tProperty",
|
|
95
|
+
],
|
|
96
|
+
artifacts: ["tGroup", "tTextAnnotation", "tText"],
|
|
97
|
+
choreography: [
|
|
98
|
+
"tCallChoreography",
|
|
99
|
+
"tChoreography",
|
|
100
|
+
"tChoreographyActivity",
|
|
101
|
+
"tChoreographyTask",
|
|
102
|
+
"tGlobalChoreographyTask",
|
|
103
|
+
"tSubChoreography",
|
|
104
|
+
],
|
|
105
|
+
conversation: [
|
|
106
|
+
"tCallConversation",
|
|
107
|
+
"tConversation",
|
|
108
|
+
"tConversationAssociation",
|
|
109
|
+
"tConversationLink",
|
|
110
|
+
"tConversationNode",
|
|
111
|
+
"tGlobalConversation",
|
|
112
|
+
"tSubConversation",
|
|
113
|
+
"tMessageFlowAssociation",
|
|
114
|
+
"tParticipantAssociation",
|
|
115
|
+
"tParticipantMultiplicity",
|
|
116
|
+
],
|
|
117
|
+
correlation: [
|
|
118
|
+
"tCorrelationKey",
|
|
119
|
+
"tCorrelationProperty",
|
|
120
|
+
"tCorrelationPropertyBinding",
|
|
121
|
+
"tCorrelationPropertyRetrievalExpression",
|
|
122
|
+
"tCorrelationSubscription",
|
|
123
|
+
],
|
|
124
|
+
services: ["tEndPoint", "tInterface", "tOperation", "tPartnerEntity", "tPartnerRole"],
|
|
125
|
+
resources: [
|
|
126
|
+
"tHumanPerformer",
|
|
127
|
+
"tPerformer",
|
|
128
|
+
"tPotentialOwner",
|
|
129
|
+
"tResource",
|
|
130
|
+
"tResourceAssignmentExpression",
|
|
131
|
+
"tResourceParameter",
|
|
132
|
+
"tResourceParameterBinding",
|
|
133
|
+
"tResourceRole",
|
|
134
|
+
],
|
|
135
|
+
callable: [
|
|
136
|
+
"tCallableElement",
|
|
137
|
+
"tCallActivity",
|
|
138
|
+
"tGlobalBusinessRuleTask",
|
|
139
|
+
"tGlobalManualTask",
|
|
140
|
+
"tGlobalScriptTask",
|
|
141
|
+
"tGlobalTask",
|
|
142
|
+
"tGlobalUserTask",
|
|
143
|
+
],
|
|
144
|
+
loops: ["tComplexBehaviorDefinition", "tLoopCharacteristics", "tMultiInstanceLoopCharacteristics", "tStandardLoopCharacteristics"],
|
|
145
|
+
"categories-and-monitoring": ["tAuditing", "tCategory", "tCategoryValue", "tMonitoring", "tRelationship"],
|
|
146
|
+
"documentation-and-extensions": [
|
|
147
|
+
"tBaseElementWithMixedContent",
|
|
148
|
+
"tDocumentation",
|
|
149
|
+
"tExtension",
|
|
150
|
+
"tExtensionElements",
|
|
151
|
+
"tRendering",
|
|
152
|
+
"tScript",
|
|
153
|
+
],
|
|
154
|
+
"di-styling": ["BPMNLabelStyle", "Font", "Style"],
|
|
155
|
+
};
|
|
156
|
+
export const OUT_OF_SCOPE_PROPERTIES = {
|
|
157
|
+
data: ["property", "ioBinding", "dataState", "itemSubjectRef"],
|
|
158
|
+
artifacts: ["artifact"],
|
|
159
|
+
choreography: ["choreographyRef", "definitionalCollaborationRef"],
|
|
160
|
+
conversation: [
|
|
161
|
+
"conversationNode",
|
|
162
|
+
"conversationAssociation",
|
|
163
|
+
"conversationLink",
|
|
164
|
+
"participantAssociation",
|
|
165
|
+
"messageFlowAssociation",
|
|
166
|
+
"participantMultiplicity",
|
|
167
|
+
"choreographyActivityShape",
|
|
168
|
+
"participantBandKind",
|
|
169
|
+
],
|
|
170
|
+
correlation: ["correlationKey", "correlationSubscription"],
|
|
171
|
+
services: ["supportedInterfaceRef", "interfaceRef", "endPointRef"],
|
|
172
|
+
resources: ["resourceRole"],
|
|
173
|
+
loops: ["loopCharacteristics"],
|
|
174
|
+
"categories-and-monitoring": ["auditing", "monitoring", "categoryValueRef", "supports"],
|
|
175
|
+
"documentation-and-extensions": ["documentation", "extensionElements", "extension", "rendering"],
|
|
176
|
+
"di-styling": ["BPMNLabelStyle", "labelStyle"],
|
|
177
|
+
derived: ["incoming", "outgoing"],
|
|
178
|
+
};
|
|
179
|
+
export const OUT_OF_SCOPE_REASONS = {
|
|
180
|
+
derived: "FlowNode.incoming and FlowNode.outgoing are derived from the sequence flows; storing them would duplicate the graph. The exporter computes them from the sequence flows.",
|
|
181
|
+
};
|
|
182
|
+
export const REAL_SCOPE = {
|
|
183
|
+
inScope: IN_SCOPE_TYPES,
|
|
184
|
+
outOfScopeTypes: OUT_OF_SCOPE_TYPES,
|
|
185
|
+
outOfScopeProperties: OUT_OF_SCOPE_PROPERTIES,
|
|
186
|
+
outOfScopeReasons: OUT_OF_SCOPE_REASONS,
|
|
187
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export type XsdMember = {
|
|
2
|
+
name: string;
|
|
3
|
+
kind: "attribute" | "element";
|
|
4
|
+
};
|
|
5
|
+
export type XsdType = {
|
|
6
|
+
file: string;
|
|
7
|
+
name: string;
|
|
8
|
+
base: string | null;
|
|
9
|
+
abstract: boolean;
|
|
10
|
+
members: XsdMember[];
|
|
11
|
+
};
|
|
12
|
+
export declare const parseXsd: (file: string, xml: string) => XsdType[];
|
|
13
|
+
export declare const XSD_FILES: string[];
|
|
14
|
+
export declare const XSD_DIR = "reference/bpmn-xsd";
|
|
15
|
+
export declare const loadXsdTypes: (root: string) => XsdType[];
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { XMLParser } from "fast-xml-parser";
|
|
4
|
+
const parser = new XMLParser({
|
|
5
|
+
ignoreAttributes: false,
|
|
6
|
+
attributeNamePrefix: "@_",
|
|
7
|
+
removeNSPrefix: true,
|
|
8
|
+
isArray: (name) => ["complexType", "element", "attribute", "sequence", "choice", "all", "complexContent", "extension"].includes(name),
|
|
9
|
+
});
|
|
10
|
+
const asList = (value) => (Array.isArray(value) ? value : value ? [value] : []);
|
|
11
|
+
const localName = (qname) => qname.replace(/^.*:/, "");
|
|
12
|
+
const collectMembers = (node, members) => {
|
|
13
|
+
for (const attribute of asList(node.attribute)) {
|
|
14
|
+
const name = (attribute["@_name"] ?? attribute["@_ref"]);
|
|
15
|
+
if (name)
|
|
16
|
+
members.push({ name: localName(name), kind: "attribute" });
|
|
17
|
+
}
|
|
18
|
+
for (const element of asList(node.element)) {
|
|
19
|
+
const name = (element["@_name"] ?? element["@_ref"]);
|
|
20
|
+
if (name)
|
|
21
|
+
members.push({ name: localName(name), kind: "element" });
|
|
22
|
+
}
|
|
23
|
+
for (const group of ["sequence", "choice", "all", "complexContent", "extension"]) {
|
|
24
|
+
for (const child of asList(node[group]))
|
|
25
|
+
collectMembers(child, members);
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
const baseOf = (node) => {
|
|
29
|
+
for (const content of asList(node.complexContent)) {
|
|
30
|
+
for (const extension of asList(content.extension)) {
|
|
31
|
+
const base = extension["@_base"];
|
|
32
|
+
if (base)
|
|
33
|
+
return localName(base);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return null;
|
|
37
|
+
};
|
|
38
|
+
export const parseXsd = (file, xml) => {
|
|
39
|
+
const schema = parser.parse(xml).schema;
|
|
40
|
+
return asList(schema.complexType).map((type) => {
|
|
41
|
+
const members = [];
|
|
42
|
+
collectMembers(type, members);
|
|
43
|
+
const seen = new Set();
|
|
44
|
+
return {
|
|
45
|
+
file,
|
|
46
|
+
name: type["@_name"],
|
|
47
|
+
base: baseOf(type),
|
|
48
|
+
abstract: type["@_abstract"] === "true",
|
|
49
|
+
members: members.filter((m) => !seen.has(`${m.kind}:${m.name}`) && seen.add(`${m.kind}:${m.name}`)),
|
|
50
|
+
};
|
|
51
|
+
});
|
|
52
|
+
};
|
|
53
|
+
export const XSD_FILES = ["Semantic.xsd", "BPMNDI.xsd", "DC.xsd", "DI.xsd"];
|
|
54
|
+
export const XSD_DIR = "reference/bpmn-xsd";
|
|
55
|
+
export const loadXsdTypes = (root) => XSD_FILES.flatMap((file) => parseXsd(file, readFileSync(join(root, XSD_DIR, file), "utf8")));
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { Store } from "n3";
|
|
2
|
+
import type { XsdType } from "./coverage-xsd.ts";
|
|
3
|
+
import type { CoverageScope } from "./coverage-scope.ts";
|
|
4
|
+
export type Status = "covered" | "gap" | "out-of-scope";
|
|
5
|
+
export type CoverageItem = {
|
|
6
|
+
id: string;
|
|
7
|
+
kind: "class" | "property";
|
|
8
|
+
xsd: string;
|
|
9
|
+
ontology: string | null;
|
|
10
|
+
status: Status;
|
|
11
|
+
group?: string;
|
|
12
|
+
reason?: string;
|
|
13
|
+
};
|
|
14
|
+
export type Counts = Record<Status, number>;
|
|
15
|
+
export type CoverageReport = {
|
|
16
|
+
summary: {
|
|
17
|
+
classes: Counts;
|
|
18
|
+
properties: Counts;
|
|
19
|
+
total: Counts;
|
|
20
|
+
};
|
|
21
|
+
unclassified: string[];
|
|
22
|
+
items: CoverageItem[];
|
|
23
|
+
};
|
|
24
|
+
export declare const checkCoverage: (store: Store, types: XsdType[], scope: CoverageScope) => CoverageReport;
|
|
25
|
+
export declare const renderMarkdown: (report: CoverageReport) => string;
|
|
26
|
+
export declare const renderJson: (report: CoverageReport) => string;
|
|
27
|
+
export declare const generateReports: (root: string) => {
|
|
28
|
+
report: CoverageReport;
|
|
29
|
+
markdown: string;
|
|
30
|
+
json: string;
|
|
31
|
+
};
|
|
32
|
+
export declare const REPORT_MARKDOWN = "reports/coverage.md";
|
|
33
|
+
export declare const REPORT_JSON = "reports/coverage.json";
|
|
34
|
+
export declare const writeReports: (root: string) => CoverageReport;
|
|
35
|
+
export declare const readReport: (root: string, file: string) => string;
|
package/dist/coverage.js
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { BPMN_NAMESPACE, BPMNDI_NAMESPACE } from "./namespace.js";
|
|
4
|
+
import { declaredClasses, declaredProperties, domainAlternatives, loadOntology, superClasses } from "./ontology.js";
|
|
5
|
+
import { loadXsdTypes } from "./coverage-xsd.js";
|
|
6
|
+
import { REAL_SCOPE } from "./coverage-scope.js";
|
|
7
|
+
import { BUILT_IN_PROPERTIES, CLASS_ALIASES, PROPERTY_ALIASES } from "./coverage-mappings.js";
|
|
8
|
+
const PREFIXES = [
|
|
9
|
+
[BPMN_NAMESPACE, "bpmn:"],
|
|
10
|
+
[BPMNDI_NAMESPACE, "bpmndi:"],
|
|
11
|
+
];
|
|
12
|
+
const compact = (iri) => {
|
|
13
|
+
for (const [namespace, prefix] of PREFIXES)
|
|
14
|
+
if (iri.startsWith(namespace))
|
|
15
|
+
return prefix + iri.slice(namespace.length);
|
|
16
|
+
return iri;
|
|
17
|
+
};
|
|
18
|
+
const semantic = (type) => type.file === "Semantic.xsd";
|
|
19
|
+
const stripPrefix = (name) => name.replace(/^t(?=[A-Z])/, "");
|
|
20
|
+
const idName = (type) => (semantic(type) ? stripPrefix(type.name) : type.name);
|
|
21
|
+
const localClassName = (type) => CLASS_ALIASES[type.name] ?? idName(type);
|
|
22
|
+
const namespaceOf = (type) => (semantic(type) ? BPMN_NAMESPACE : BPMNDI_NAMESPACE);
|
|
23
|
+
const groupOf = (groups, name) => Object.entries(groups).find(([, members]) => members.includes(name))?.[0];
|
|
24
|
+
const emptyCounts = () => ({ covered: 0, gap: 0, "out-of-scope": 0 });
|
|
25
|
+
const propertyCovered = (store, classIri, property) => {
|
|
26
|
+
const ancestors = new Set([classIri, ...superClasses(store, classIri)]);
|
|
27
|
+
const statements = domainAlternatives(store, property);
|
|
28
|
+
return statements.length === 0 || statements.some((alternatives) => alternatives.some((c) => ancestors.has(c)));
|
|
29
|
+
};
|
|
30
|
+
const reasonOf = (scope, group) => {
|
|
31
|
+
const reason = scope.outOfScopeReasons?.[group];
|
|
32
|
+
return reason ? { reason } : {};
|
|
33
|
+
};
|
|
34
|
+
export const checkCoverage = (store, types, scope) => {
|
|
35
|
+
const classes = declaredClasses(store);
|
|
36
|
+
const properties = declaredProperties(store);
|
|
37
|
+
const items = [];
|
|
38
|
+
const unclassified = [];
|
|
39
|
+
for (const type of types) {
|
|
40
|
+
const local = idName(type);
|
|
41
|
+
const classIri = namespaceOf(type) + localClassName(type);
|
|
42
|
+
const xsd = `${type.file}#${type.name}`;
|
|
43
|
+
if (!scope.inScope.includes(type.name)) {
|
|
44
|
+
const group = groupOf(scope.outOfScopeTypes, type.name);
|
|
45
|
+
if (group)
|
|
46
|
+
items.push({ id: local, kind: "class", xsd, ontology: null, status: "out-of-scope", group, ...reasonOf(scope, group) });
|
|
47
|
+
else
|
|
48
|
+
unclassified.push(xsd);
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
const covered = classes.has(classIri);
|
|
52
|
+
items.push({ id: local, kind: "class", xsd, ontology: compact(classIri), status: covered ? "covered" : "gap" });
|
|
53
|
+
for (const member of type.members) {
|
|
54
|
+
const memberXsd = `${xsd}/${member.kind === "attribute" ? "@" : ""}${member.name}`;
|
|
55
|
+
const id = `${local}.${member.name}`;
|
|
56
|
+
const builtIn = BUILT_IN_PROPERTIES[member.name];
|
|
57
|
+
if (builtIn) {
|
|
58
|
+
items.push({ id, kind: "property", xsd: memberXsd, ontology: builtIn, status: "covered" });
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
const alias = PROPERTY_ALIASES[`${local}.${member.name}`] ?? PROPERTY_ALIASES[member.name] ?? member.name;
|
|
62
|
+
const candidates = [BPMN_NAMESPACE + alias, BPMNDI_NAMESPACE + alias].filter((iri) => properties.has(iri));
|
|
63
|
+
const hit = candidates.find((iri) => propertyCovered(store, classIri, iri));
|
|
64
|
+
if (hit) {
|
|
65
|
+
items.push({ id, kind: "property", xsd: memberXsd, ontology: compact(hit), status: "covered" });
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
const group = groupOf(scope.outOfScopeProperties, member.name);
|
|
69
|
+
if (group)
|
|
70
|
+
items.push({ id, kind: "property", xsd: memberXsd, ontology: null, status: "out-of-scope", group, ...reasonOf(scope, group) });
|
|
71
|
+
else
|
|
72
|
+
items.push({ id, kind: "property", xsd: memberXsd, ontology: null, status: "gap" });
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
items.sort((a, b) => (a.kind === b.kind ? a.id.localeCompare(b.id) : a.kind === "class" ? -1 : 1));
|
|
76
|
+
unclassified.sort();
|
|
77
|
+
const summary = { classes: emptyCounts(), properties: emptyCounts(), total: emptyCounts() };
|
|
78
|
+
for (const item of items) {
|
|
79
|
+
summary[item.kind === "class" ? "classes" : "properties"][item.status]++;
|
|
80
|
+
summary.total[item.status]++;
|
|
81
|
+
}
|
|
82
|
+
return { summary, unclassified, items };
|
|
83
|
+
};
|
|
84
|
+
const table = (rows, columns, cell) => rows.length
|
|
85
|
+
? [
|
|
86
|
+
`| ${columns.join(" | ")} |`,
|
|
87
|
+
`| ${columns.map(() => "---").join(" | ")} |`,
|
|
88
|
+
...rows.map((item) => `| ${cell(item).join(" | ")} |`),
|
|
89
|
+
].join("\n")
|
|
90
|
+
: "_None._";
|
|
91
|
+
export const renderMarkdown = (report) => {
|
|
92
|
+
const { summary, items } = report;
|
|
93
|
+
const inScope = items.filter((i) => i.status !== "out-of-scope");
|
|
94
|
+
const gaps = items.filter((i) => i.status === "gap");
|
|
95
|
+
const covered = items.filter((i) => i.status === "covered");
|
|
96
|
+
const out = items.filter((i) => i.status === "out-of-scope");
|
|
97
|
+
const groups = [...new Set(out.map((i) => i.group))].sort();
|
|
98
|
+
const lines = [
|
|
99
|
+
"# BPMN coverage report",
|
|
100
|
+
"",
|
|
101
|
+
"Generated by `npm run coverage` from the normative BPMN 2.0.2 XSDs in `reference/bpmn-xsd/` and the ontology in `ontology/`. Do not edit by hand.",
|
|
102
|
+
"",
|
|
103
|
+
"## Summary",
|
|
104
|
+
"",
|
|
105
|
+
"| Kind | Covered | Gaps | Out of scope |",
|
|
106
|
+
"| --- | ---: | ---: | ---: |",
|
|
107
|
+
...["classes", "properties", "total"].map((k) => `| ${k} | ${summary[k].covered} | ${summary[k].gap} | ${summary[k]["out-of-scope"]} |`),
|
|
108
|
+
"",
|
|
109
|
+
`In scope: ${inScope.length} items, ${summary.total.covered} covered and ${summary.total.gap} gaps.`,
|
|
110
|
+
"",
|
|
111
|
+
`## Gaps (${gaps.length})`,
|
|
112
|
+
"",
|
|
113
|
+
table(gaps, ["Kind", "Item", "XSD"], (i) => [i.kind, `\`${i.id}\``, `\`${i.xsd}\``]),
|
|
114
|
+
"",
|
|
115
|
+
`## Covered (${covered.length})`,
|
|
116
|
+
"",
|
|
117
|
+
table(covered, ["Kind", "Item", "XSD", "Ontology"], (i) => [i.kind, `\`${i.id}\``, `\`${i.xsd}\``, `\`${i.ontology}\``]),
|
|
118
|
+
"",
|
|
119
|
+
`## Out of scope (${out.length})`,
|
|
120
|
+
"",
|
|
121
|
+
...groups.flatMap((group) => {
|
|
122
|
+
const members = out.filter((i) => i.group === group);
|
|
123
|
+
const reason = members.find((i) => i.reason)?.reason;
|
|
124
|
+
return [
|
|
125
|
+
`### ${group} (${members.length})`,
|
|
126
|
+
"",
|
|
127
|
+
...(reason ? [reason, ""] : []),
|
|
128
|
+
members.map((i) => `\`${i.kind === "class" ? i.xsd : i.id}\``).join(", "),
|
|
129
|
+
"",
|
|
130
|
+
];
|
|
131
|
+
}),
|
|
132
|
+
];
|
|
133
|
+
if (report.unclassified.length) {
|
|
134
|
+
lines.push(`## Unclassified (${report.unclassified.length})`, "", report.unclassified.map((u) => `\`${u}\``).join(", "), "");
|
|
135
|
+
}
|
|
136
|
+
return lines.join("\n").replace(/\n+$/, "\n");
|
|
137
|
+
};
|
|
138
|
+
export const renderJson = (report) => `${JSON.stringify(report, null, 2)}\n`;
|
|
139
|
+
export const generateReports = (root) => {
|
|
140
|
+
const report = checkCoverage(loadOntology(), loadXsdTypes(root), REAL_SCOPE);
|
|
141
|
+
return { report, markdown: renderMarkdown(report), json: renderJson(report) };
|
|
142
|
+
};
|
|
143
|
+
export const REPORT_MARKDOWN = "reports/coverage.md";
|
|
144
|
+
export const REPORT_JSON = "reports/coverage.json";
|
|
145
|
+
export const writeReports = (root) => {
|
|
146
|
+
const { report, markdown, json } = generateReports(root);
|
|
147
|
+
mkdirSync(join(root, "reports"), { recursive: true });
|
|
148
|
+
writeFileSync(join(root, REPORT_MARKDOWN), markdown);
|
|
149
|
+
writeFileSync(join(root, REPORT_JSON), json);
|
|
150
|
+
return report;
|
|
151
|
+
};
|
|
152
|
+
export const readReport = (root, file) => readFileSync(join(root, file), "utf8");
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/docs-cli.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { checkVocabulary, writeVocabulary } from "./docs.js";
|
|
2
|
+
const args = process.argv.slice(2);
|
|
3
|
+
const check = args.includes("--check");
|
|
4
|
+
const path = args.find((arg) => !arg.startsWith("--"));
|
|
5
|
+
if (check) {
|
|
6
|
+
const result = checkVocabulary(path);
|
|
7
|
+
if (result.ok) {
|
|
8
|
+
console.log(result.message);
|
|
9
|
+
}
|
|
10
|
+
else {
|
|
11
|
+
console.error(result.message);
|
|
12
|
+
process.exitCode = 1;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
else {
|
|
16
|
+
writeVocabulary(path);
|
|
17
|
+
console.log(`wrote ${path ?? "docs/reference/vocabulary.md"}`);
|
|
18
|
+
}
|
package/dist/docs.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Store } from "n3";
|
|
2
|
+
export declare const VOCABULARY_PATH = "docs/reference/vocabulary.md";
|
|
3
|
+
export declare const renderVocabulary: (store?: Store) => string;
|
|
4
|
+
export declare const writeVocabulary: (path?: string, store?: Store) => void;
|
|
5
|
+
export declare const checkVocabulary: (path?: string, store?: Store) => {
|
|
6
|
+
ok: boolean;
|
|
7
|
+
message: string;
|
|
8
|
+
};
|
package/dist/docs.js
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
import { BPMN_NAMESPACE, BPMNDI_NAMESPACE } from "./namespace.js";
|
|
4
|
+
import { ROOT } from "./paths.js";
|
|
5
|
+
import { rangeAlternatives, declaredClasses, declaredIndividuals, declaredProperties, domainAlternatives, isSubClassOf, loadOntology, typesOf, } from "./ontology.js";
|
|
6
|
+
export const VOCABULARY_PATH = "docs/reference/vocabulary.md";
|
|
7
|
+
const RDFS = "http://www.w3.org/2000/01/rdf-schema#";
|
|
8
|
+
const OWL_OBJECT_PROPERTY = "http://www.w3.org/2002/07/owl#ObjectProperty";
|
|
9
|
+
const XSD = "http://www.w3.org/2001/XMLSchema#";
|
|
10
|
+
const MODULES = [
|
|
11
|
+
{ title: "Core", prefix: "bpmn", namespace: BPMN_NAMESPACE },
|
|
12
|
+
{ title: "Diagram interchange", prefix: "bpmndi", namespace: BPMNDI_NAMESPACE },
|
|
13
|
+
];
|
|
14
|
+
const compact = (iri) => {
|
|
15
|
+
const module = MODULES.find((m) => iri.startsWith(m.namespace));
|
|
16
|
+
if (module)
|
|
17
|
+
return `${module.prefix}:${iri.slice(module.namespace.length)}`;
|
|
18
|
+
return iri.startsWith(XSD) ? `xsd:${iri.slice(XSD.length)}` : iri;
|
|
19
|
+
};
|
|
20
|
+
const byCompact = (a, b) => compact(a).localeCompare(compact(b));
|
|
21
|
+
const cell = (text) => text.replace(/\|/g, "\\|").replace(/\s+/g, " ").trim();
|
|
22
|
+
const comment = (store, iri) => store.getObjects(iri, `${RDFS}comment`, null).map((o) => o.value).sort().join(" ") || "No definition.";
|
|
23
|
+
const code = (iri) => `\`${compact(iri)}\``;
|
|
24
|
+
const list = (iris) => (iris.length ? [...iris].sort(byCompact).map(code).join(", ") : "none");
|
|
25
|
+
const directSuperClasses = (store, cls) => store.getObjects(cls, `${RDFS}subClassOf`, null).filter((o) => o.termType === "NamedNode").map((o) => o.value);
|
|
26
|
+
const ancestorsOf = (store, cls) => {
|
|
27
|
+
const result = new Set();
|
|
28
|
+
const walk = (current) => {
|
|
29
|
+
for (const parent of directSuperClasses(store, current)) {
|
|
30
|
+
if (!result.has(parent)) {
|
|
31
|
+
result.add(parent);
|
|
32
|
+
walk(parent);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
walk(cls);
|
|
37
|
+
return [...result];
|
|
38
|
+
};
|
|
39
|
+
const domainText = (store, property) => {
|
|
40
|
+
const alternatives = domainAlternatives(store, property);
|
|
41
|
+
return alternatives.length
|
|
42
|
+
? alternatives.map((members) => [...members].sort(byCompact).map(code).join(" or ")).join("; and ")
|
|
43
|
+
: "unspecified";
|
|
44
|
+
};
|
|
45
|
+
const rangeText = (store, property) => {
|
|
46
|
+
const ranges = rangeAlternatives(store, property);
|
|
47
|
+
return ranges.length ? ranges.map((members) => [...members].sort(byCompact).map(code).join(" or ")).sort().join(", ") : "unspecified";
|
|
48
|
+
};
|
|
49
|
+
const appliesTo = (store, property, cls) => domainAlternatives(store, property).some((members) => members.some((member) => isSubClassOf(store, cls, member)));
|
|
50
|
+
const renderClass = (store, cls, properties) => {
|
|
51
|
+
const subClasses = [...declaredClasses(store)].filter((c) => directSuperClasses(store, c).includes(cls));
|
|
52
|
+
const applicable = properties.filter((p) => appliesTo(store, p, cls));
|
|
53
|
+
const lines = [
|
|
54
|
+
`#### ${code(cls)}`,
|
|
55
|
+
"",
|
|
56
|
+
comment(store, cls),
|
|
57
|
+
"",
|
|
58
|
+
`- Superclasses: ${list(directSuperClasses(store, cls))}`,
|
|
59
|
+
`- All ancestors: ${list(ancestorsOf(store, cls))}`,
|
|
60
|
+
`- Subclasses: ${list(subClasses)}`,
|
|
61
|
+
"",
|
|
62
|
+
];
|
|
63
|
+
if (applicable.length) {
|
|
64
|
+
lines.push("| Property | Range | Definition |", "| --- | --- | --- |");
|
|
65
|
+
for (const property of applicable) {
|
|
66
|
+
lines.push(`| ${code(property)} | ${rangeText(store, property)} | ${cell(comment(store, property))} |`);
|
|
67
|
+
}
|
|
68
|
+
lines.push("");
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
lines.push("No properties apply.", "");
|
|
72
|
+
}
|
|
73
|
+
return lines;
|
|
74
|
+
};
|
|
75
|
+
const renderProperty = (store, property) => {
|
|
76
|
+
const kind = typesOf(store, property).includes(OWL_OBJECT_PROPERTY) ? "object" : "datatype";
|
|
77
|
+
return [
|
|
78
|
+
`#### ${code(property)}`,
|
|
79
|
+
"",
|
|
80
|
+
comment(store, property),
|
|
81
|
+
"",
|
|
82
|
+
`- Kind: ${kind}`,
|
|
83
|
+
`- Domain: ${domainText(store, property)}`,
|
|
84
|
+
`- Range: ${rangeText(store, property)}`,
|
|
85
|
+
"",
|
|
86
|
+
];
|
|
87
|
+
};
|
|
88
|
+
const renderIndividual = (store, individual) => {
|
|
89
|
+
const classes = typesOf(store, individual).filter((t) => declaredClasses(store).has(t));
|
|
90
|
+
return [`#### ${code(individual)}`, "", comment(store, individual), "", `- Type: ${list(classes)}`, ""];
|
|
91
|
+
};
|
|
92
|
+
export const renderVocabulary = (store = loadOntology()) => {
|
|
93
|
+
const classes = declaredClasses(store);
|
|
94
|
+
const properties = declaredProperties(store);
|
|
95
|
+
const individuals = declaredIndividuals(store);
|
|
96
|
+
const lines = [
|
|
97
|
+
"# Vocabulary reference",
|
|
98
|
+
"",
|
|
99
|
+
"Generated from the ontology by `npm run docs`. Do not edit by hand.",
|
|
100
|
+
"",
|
|
101
|
+
...MODULES.map((m) => `- \`${m.prefix}:\` expands to \`${m.namespace}\``),
|
|
102
|
+
"",
|
|
103
|
+
];
|
|
104
|
+
for (const module of MODULES) {
|
|
105
|
+
const inModule = (iri) => iri.startsWith(module.namespace);
|
|
106
|
+
const moduleClasses = [...classes].filter(inModule).sort(byCompact);
|
|
107
|
+
const moduleProperties = [...properties].filter(inModule).sort(byCompact);
|
|
108
|
+
const moduleIndividuals = [...individuals].filter(inModule).sort(byCompact);
|
|
109
|
+
const applicableProperties = [...properties].sort(byCompact);
|
|
110
|
+
lines.push(`## ${module.title} module (\`${module.prefix}:\`)`, "");
|
|
111
|
+
lines.push("### Classes", "");
|
|
112
|
+
for (const cls of moduleClasses)
|
|
113
|
+
lines.push(...renderClass(store, cls, applicableProperties));
|
|
114
|
+
lines.push("### Properties", "");
|
|
115
|
+
for (const property of moduleProperties)
|
|
116
|
+
lines.push(...renderProperty(store, property));
|
|
117
|
+
if (moduleIndividuals.length) {
|
|
118
|
+
lines.push("### Named individuals", "");
|
|
119
|
+
for (const individual of moduleIndividuals)
|
|
120
|
+
lines.push(...renderIndividual(store, individual));
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return `${lines.join("\n").replace(/\n+$/, "")}\n`;
|
|
124
|
+
};
|
|
125
|
+
export const writeVocabulary = (path = join(ROOT, VOCABULARY_PATH), store) => {
|
|
126
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
127
|
+
writeFileSync(path, renderVocabulary(store));
|
|
128
|
+
};
|
|
129
|
+
export const checkVocabulary = (path = join(ROOT, VOCABULARY_PATH), store) => {
|
|
130
|
+
const expected = renderVocabulary(store);
|
|
131
|
+
const actual = existsSync(path) ? readFileSync(path, "utf8") : null;
|
|
132
|
+
if (actual === expected)
|
|
133
|
+
return { ok: true, message: `${path} is up to date` };
|
|
134
|
+
const reason = actual === null ? "is missing" : "differs from the ontology";
|
|
135
|
+
return { ok: false, message: `${path} ${reason}; run npm run docs and commit the result` };
|
|
136
|
+
};
|