@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
package/dist/render.d.ts
ADDED
package/dist/render.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export type Schema = Record<string, any>;
|
|
2
|
+
export interface OverrideContext {
|
|
3
|
+
schema: Schema;
|
|
4
|
+
classesUnder: (term: string) => string[];
|
|
5
|
+
}
|
|
6
|
+
export interface SchemaOverride {
|
|
7
|
+
name: string;
|
|
8
|
+
apply: (context: OverrideContext) => void;
|
|
9
|
+
}
|
|
10
|
+
export declare const requireIdOnFlowElements: SchemaOverride;
|
|
11
|
+
export declare const waypointsNeedTwoPoints: SchemaOverride;
|
|
12
|
+
export declare const requireTopLevelContext: SchemaOverride;
|
|
13
|
+
export declare const diagramElementsReferenceTheirElement: SchemaOverride;
|
|
14
|
+
export declare const schemaOverrides: SchemaOverride[];
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
const addRequired = (target, ...names) => {
|
|
2
|
+
target.required = [...new Set([...(target.required ?? []), ...names])];
|
|
3
|
+
};
|
|
4
|
+
export const requireIdOnFlowElements = {
|
|
5
|
+
name: "require-id-on-flow-elements",
|
|
6
|
+
apply: ({ schema, classesUnder }) => {
|
|
7
|
+
for (const term of classesUnder("FlowElement"))
|
|
8
|
+
addRequired(schema.$defs[term], "id");
|
|
9
|
+
},
|
|
10
|
+
};
|
|
11
|
+
export const waypointsNeedTwoPoints = {
|
|
12
|
+
name: "waypoints-need-two-points",
|
|
13
|
+
apply: ({ schema }) => {
|
|
14
|
+
schema.$defs.BPMNEdge.properties.waypoints.minItems = 2;
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
export const requireTopLevelContext = {
|
|
18
|
+
name: "require-top-level-context",
|
|
19
|
+
apply: ({ schema }) => {
|
|
20
|
+
addRequired(schema.$defs.topLevelNode, "@context");
|
|
21
|
+
addRequired(schema.$defs.graphDocument, "@context");
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
export const diagramElementsReferenceTheirElement = {
|
|
25
|
+
name: "diagram-elements-reference-their-element",
|
|
26
|
+
apply: ({ schema }) => {
|
|
27
|
+
for (const term of ["BPMNShape", "BPMNEdge"])
|
|
28
|
+
addRequired(schema.$defs[term], "bpmnElement");
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
export const schemaOverrides = [
|
|
32
|
+
requireIdOnFlowElements,
|
|
33
|
+
waypointsNeedTwoPoints,
|
|
34
|
+
requireTopLevelContext,
|
|
35
|
+
diagramElementsReferenceTheirElement,
|
|
36
|
+
];
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import Ajv2020 from "ajv/dist/2020.js";
|
|
2
|
+
import type { Schema } from "./schema-overrides.ts";
|
|
3
|
+
export declare const loadSchema: () => Schema;
|
|
4
|
+
export declare const compileSchema: (schema?: Schema) => Ajv2020.ValidateFunction<unknown>;
|
|
5
|
+
export declare const validateWithSchema: (document: unknown, validate?: Ajv2020.ValidateFunction<unknown>) => string[];
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import Ajv2020 from "ajv/dist/2020.js";
|
|
4
|
+
import { ROOT } from "./paths.js";
|
|
5
|
+
import { SCHEMA_PATH } from "./build.js";
|
|
6
|
+
export const loadSchema = () => JSON.parse(readFileSync(join(ROOT, SCHEMA_PATH), "utf8"));
|
|
7
|
+
export const compileSchema = (schema = loadSchema()) => new Ajv2020.default({ allErrors: false, logger: false }).compile(schema);
|
|
8
|
+
export const validateWithSchema = (document, validate = compileSchema()) => validate(document) ? [] : (validate.errors ?? []).map((e) => `${e.instancePath || "/"} ${e.message}`);
|
package/dist/schema.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { Schema, SchemaOverride } from "./schema-overrides.ts";
|
|
2
|
+
export interface GenerateOptions {
|
|
3
|
+
overrides?: SchemaOverride[];
|
|
4
|
+
}
|
|
5
|
+
export declare const generateSchema: ({ overrides }?: GenerateOptions) => Schema;
|
|
6
|
+
export declare const renderSchema: (options?: GenerateOptions) => string;
|
package/dist/schema.js
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { ROOT } from "./paths.js";
|
|
4
|
+
import { BPMN_NAMESPACE } from "./namespace.js";
|
|
5
|
+
import { declaredClasses, declaredIndividuals, domainAlternatives, isSubClassOf, loadOntology, rangeAlternatives, typesOf, } from "./ontology.js";
|
|
6
|
+
import { schemaOverrides } from "./schema-overrides.js";
|
|
7
|
+
const CONTEXT_FILES = ["contexts/core.jsonld", "contexts/di.jsonld"];
|
|
8
|
+
const XSD = "http://www.w3.org/2001/XMLSchema#";
|
|
9
|
+
const KEYWORD_TERMS = new Set(["id", "type"]);
|
|
10
|
+
const loadContextTerms = () => Object.assign({}, ...CONTEXT_FILES.map((file) => JSON.parse(readFileSync(join(ROOT, file), "utf8"))["@context"]));
|
|
11
|
+
const readContext = (store) => {
|
|
12
|
+
const terms = loadContextTerms();
|
|
13
|
+
const prefixes = new Map(Object.entries(terms).filter(([key, value]) => !key.startsWith("@") && typeof value === "string" && value.endsWith("#")));
|
|
14
|
+
const expand = (value) => {
|
|
15
|
+
const [prefix, local] = value.split(":");
|
|
16
|
+
return prefixes.has(prefix) ? prefixes.get(prefix) + local : undefined;
|
|
17
|
+
};
|
|
18
|
+
const classes = declaredClasses(store);
|
|
19
|
+
const individuals = declaredIndividuals(store);
|
|
20
|
+
const model = { classTerms: new Map(), individualTerms: new Map(), properties: [] };
|
|
21
|
+
for (const [term, definition] of Object.entries(terms)) {
|
|
22
|
+
if (term.startsWith("@") || prefixes.has(term) || KEYWORD_TERMS.has(term))
|
|
23
|
+
continue;
|
|
24
|
+
const spec = typeof definition === "string" ? { "@id": definition } : definition;
|
|
25
|
+
const iri = expand(spec["@id"]);
|
|
26
|
+
if (!iri)
|
|
27
|
+
continue;
|
|
28
|
+
if (classes.has(iri))
|
|
29
|
+
model.classTerms.set(iri, term);
|
|
30
|
+
else if (individuals.has(iri))
|
|
31
|
+
model.individualTerms.set(iri, term);
|
|
32
|
+
else
|
|
33
|
+
model.properties.push({ term, iri, coerce: spec["@type"], container: spec["@container"] });
|
|
34
|
+
}
|
|
35
|
+
return model;
|
|
36
|
+
};
|
|
37
|
+
const ref = (name) => ({ $ref: `#/$defs/${name}` });
|
|
38
|
+
const idReference = {
|
|
39
|
+
anyOf: [
|
|
40
|
+
{ type: "string" },
|
|
41
|
+
{ type: "object", properties: { id: { type: "string" } }, required: ["id"], additionalProperties: false },
|
|
42
|
+
],
|
|
43
|
+
};
|
|
44
|
+
const datatypeSchema = (datatype) => {
|
|
45
|
+
const local = datatype.slice(XSD.length);
|
|
46
|
+
if (local === "boolean")
|
|
47
|
+
return { type: "boolean" };
|
|
48
|
+
if (local === "string")
|
|
49
|
+
return { type: "string" };
|
|
50
|
+
if (local === "integer")
|
|
51
|
+
return { type: "integer" };
|
|
52
|
+
if (local === "nonNegativeInteger")
|
|
53
|
+
return { type: "integer", minimum: 0 };
|
|
54
|
+
return { type: "number" };
|
|
55
|
+
};
|
|
56
|
+
export const generateSchema = ({ overrides = schemaOverrides } = {}) => {
|
|
57
|
+
const store = loadOntology();
|
|
58
|
+
const model = readContext(store);
|
|
59
|
+
const concrete = [...model.classTerms.entries()];
|
|
60
|
+
const subclassTerms = (ancestor) => concrete.filter(([cls]) => isSubClassOf(store, cls, ancestor)).map(([, term]) => term);
|
|
61
|
+
const valueSchema = (property) => {
|
|
62
|
+
const [alternatives = []] = rangeAlternatives(store, property.iri);
|
|
63
|
+
const [range] = alternatives;
|
|
64
|
+
if (property.coerce === "@id")
|
|
65
|
+
return idReference;
|
|
66
|
+
if (property.coerce === "@vocab") {
|
|
67
|
+
const values = [...model.individualTerms].filter(([individual]) => typesOf(store, individual).includes(range)).map(([, term]) => term);
|
|
68
|
+
return { enum: values };
|
|
69
|
+
}
|
|
70
|
+
if (range.startsWith(XSD))
|
|
71
|
+
return datatypeSchema(range);
|
|
72
|
+
return { anyOf: [...new Set(alternatives.flatMap(subclassTerms))].map(ref) };
|
|
73
|
+
};
|
|
74
|
+
const propertySchema = (property) => {
|
|
75
|
+
const value = valueSchema(property);
|
|
76
|
+
const many = { type: "array", items: value };
|
|
77
|
+
return property.container === "@set" || property.container === "@list" ? many : { anyOf: [value, many] };
|
|
78
|
+
};
|
|
79
|
+
const appliesTo = (property, cls) => domainAlternatives(store, property.iri).every((group) => group.some((domain) => isSubClassOf(store, cls, domain)));
|
|
80
|
+
const defs = {};
|
|
81
|
+
for (const [cls, term] of concrete) {
|
|
82
|
+
const own = model.properties.filter((property) => appliesTo(property, cls));
|
|
83
|
+
const foreign = model.properties.filter((property) => !own.includes(property)).map((property) => property.term);
|
|
84
|
+
defs[term] = {
|
|
85
|
+
type: "object",
|
|
86
|
+
properties: {
|
|
87
|
+
id: { type: "string" },
|
|
88
|
+
type: { const: term },
|
|
89
|
+
...Object.fromEntries(own.map((property) => [property.term, propertySchema(property)])),
|
|
90
|
+
},
|
|
91
|
+
required: ["type"],
|
|
92
|
+
propertyNames: { not: { enum: foreign } },
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
defs.node = { anyOf: concrete.map(([, term]) => ref(term)) };
|
|
96
|
+
defs.topLevelNode = { allOf: [ref("node")] };
|
|
97
|
+
defs.graphDocument = {
|
|
98
|
+
type: "object",
|
|
99
|
+
properties: { "@graph": { type: "array", items: ref("node") } },
|
|
100
|
+
required: ["@graph"],
|
|
101
|
+
};
|
|
102
|
+
defs.document = { anyOf: [ref("graphDocument"), ref("topLevelNode")] };
|
|
103
|
+
const schema = {
|
|
104
|
+
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
105
|
+
title: "BPMN-LD document",
|
|
106
|
+
anyOf: [ref("document"), { type: "array", items: ref("document") }],
|
|
107
|
+
$defs: defs,
|
|
108
|
+
};
|
|
109
|
+
const classesUnder = (name) => subclassTerms(`${BPMN_NAMESPACE}${name}`);
|
|
110
|
+
for (const override of overrides)
|
|
111
|
+
override.apply({ schema, classesUnder });
|
|
112
|
+
return schema;
|
|
113
|
+
};
|
|
114
|
+
export const renderSchema = (options) => `${JSON.stringify(generateSchema(options), null, 2)}\n`;
|
package/dist/shacl.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export declare const SHAPES_FILES: string[];
|
|
2
|
+
export interface Violation {
|
|
3
|
+
sourceShape: string;
|
|
4
|
+
focusNode: string;
|
|
5
|
+
}
|
|
6
|
+
export interface ExpectedViolations {
|
|
7
|
+
violations: Violation[];
|
|
8
|
+
}
|
|
9
|
+
export interface ShaclResult {
|
|
10
|
+
conforms: boolean;
|
|
11
|
+
violations: Violation[];
|
|
12
|
+
}
|
|
13
|
+
export declare const resolveShape: (name: string) => string;
|
|
14
|
+
export declare const validateShacl: (file: string) => Promise<ShaclResult>;
|
|
15
|
+
export declare const sameViolations: (actual: Violation[], expected: Violation[]) => boolean;
|
package/dist/shacl.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { pathToFileURL } from "node:url";
|
|
4
|
+
import { Parser, Store } from "n3";
|
|
5
|
+
import jsonld from "jsonld";
|
|
6
|
+
import rdf from "@rdfjs/dataset";
|
|
7
|
+
import SHACLValidator from "rdf-validate-shacl";
|
|
8
|
+
import { ROOT } from "./paths.js";
|
|
9
|
+
import { BPMN_SHAPES_NAMESPACE } from "./namespace.js";
|
|
10
|
+
import { fileDocumentLoader } from "./loader.js";
|
|
11
|
+
import { loadOntology, RDFS_SUBCLASS_OF } from "./ontology.js";
|
|
12
|
+
export const SHAPES_FILES = ["shapes/core.shapes.ttl"];
|
|
13
|
+
const loadShapes = () => rdf.dataset(new Parser().parse(SHAPES_FILES.map((file) => readFileSync(join(ROOT, file), "utf8")).join("\n")));
|
|
14
|
+
export const resolveShape = (name) => (name.includes(":") ? name : `${BPMN_SHAPES_NAMESPACE}${name}`);
|
|
15
|
+
export const validateShacl = async (file) => {
|
|
16
|
+
const nquads = (await jsonld.toRDF(JSON.parse(readFileSync(file, "utf8")), {
|
|
17
|
+
base: pathToFileURL(file).href,
|
|
18
|
+
documentLoader: fileDocumentLoader,
|
|
19
|
+
format: "application/n-quads",
|
|
20
|
+
safe: true,
|
|
21
|
+
}));
|
|
22
|
+
const data = rdf.dataset(new Parser().parse(nquads));
|
|
23
|
+
for (const quad of loadOntology().getQuads(null, RDFS_SUBCLASS_OF, null, null))
|
|
24
|
+
data.add(quad);
|
|
25
|
+
const report = await new SHACLValidator(loadShapes()).validate(data);
|
|
26
|
+
const violations = report.results.map((result) => ({
|
|
27
|
+
sourceShape: result.sourceShape?.value ?? "",
|
|
28
|
+
focusNode: result.focusNode?.value ?? "",
|
|
29
|
+
}));
|
|
30
|
+
return { conforms: report.conforms, violations };
|
|
31
|
+
};
|
|
32
|
+
export const sameViolations = (actual, expected) => {
|
|
33
|
+
const key = (v) => `${v.sourceShape} ${v.focusNode}`;
|
|
34
|
+
const a = actual.map(key).sort();
|
|
35
|
+
const e = expected.map((v) => key({ ...v, sourceShape: resolveShape(v.sourceShape) })).sort();
|
|
36
|
+
return a.length === e.length && a.every((value, i) => value === e[i]);
|
|
37
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { relative } from "node:path";
|
|
2
|
+
import { ROOT } from "./paths.js";
|
|
3
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
4
|
+
import { findExamples, validateExample } from "./validate.js";
|
|
5
|
+
import { sameViolations, validateShacl } from "./shacl.js";
|
|
6
|
+
import { compileSchema, validateWithSchema } from "./schema-validate.js";
|
|
7
|
+
export const EXIT_OK = 0;
|
|
8
|
+
export const EXIT_FAILED = 1;
|
|
9
|
+
const lines = [];
|
|
10
|
+
const log = (line) => lines.push(line);
|
|
11
|
+
export const runValidate = async (argv) => {
|
|
12
|
+
lines.length = 0;
|
|
13
|
+
const examplesDir = argv.find((arg) => !arg.startsWith("-")) ?? `${ROOT}examples`;
|
|
14
|
+
const validateSchema = compileSchema();
|
|
15
|
+
const schemaErrors = (file) => validateWithSchema(JSON.parse(readFileSync(file, "utf8")), validateSchema);
|
|
16
|
+
const examplesIn = (kind) => (existsSync(`${examplesDir}/${kind}`) ? findExamples(`${examplesDir}/${kind}`) : []);
|
|
17
|
+
let failed = 0;
|
|
18
|
+
const report = (label, errors) => {
|
|
19
|
+
if (errors.length === 0)
|
|
20
|
+
log(`ok ${label}`);
|
|
21
|
+
else {
|
|
22
|
+
failed++;
|
|
23
|
+
log(`FAIL ${label}`);
|
|
24
|
+
errors.forEach((e) => log(` ${e}`));
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
for (const file of [...examplesIn("positive"), ...examplesIn("miwg")]) {
|
|
28
|
+
const structural = await validateExample(file);
|
|
29
|
+
const errors = [...structural.errors, ...schemaErrors(file).map((e) => `schema: ${e}`)];
|
|
30
|
+
if (structural.valid) {
|
|
31
|
+
const shacl = await validateShacl(file);
|
|
32
|
+
shacl.violations.forEach((v) => errors.push(`${v.focusNode} violates ${v.sourceShape}`));
|
|
33
|
+
if (!shacl.conforms && shacl.violations.length === 0)
|
|
34
|
+
errors.push("SHACL validation failed");
|
|
35
|
+
}
|
|
36
|
+
report(relative(examplesDir, file), errors);
|
|
37
|
+
}
|
|
38
|
+
for (const file of examplesIn("negative")) {
|
|
39
|
+
const errors = [];
|
|
40
|
+
const structural = await validateExample(file);
|
|
41
|
+
errors.push(...structural.errors, ...schemaErrors(file).map((e) => `schema: ${e}`));
|
|
42
|
+
if (structural.valid) {
|
|
43
|
+
const expected = JSON.parse(readFileSync(file.replace(/\.jsonld$/, ".expect.json"), "utf8"));
|
|
44
|
+
const shacl = await validateShacl(file);
|
|
45
|
+
if (shacl.conforms)
|
|
46
|
+
errors.push("expected SHACL violations but the example conforms");
|
|
47
|
+
else if (!sameViolations(shacl.violations, expected.violations)) {
|
|
48
|
+
errors.push(`violations differ from the stated intent`);
|
|
49
|
+
shacl.violations.forEach((v) => errors.push(`actual: ${v.focusNode} violates ${v.sourceShape}`));
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
report(relative(examplesDir, file), errors);
|
|
53
|
+
}
|
|
54
|
+
for (const file of examplesIn("schema-negative")) {
|
|
55
|
+
report(relative(examplesDir, file), schemaErrors(file).length > 0 ? [] : ["expected the schema to reject the example but it was accepted"]);
|
|
56
|
+
}
|
|
57
|
+
return { exitCode: failed ? EXIT_FAILED : EXIT_OK, stdout: `${lines.join("\n")}\n`, stderr: "" };
|
|
58
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface ValidationResult {
|
|
2
|
+
valid: boolean;
|
|
3
|
+
errors: string[];
|
|
4
|
+
}
|
|
5
|
+
export type Node = Record<string, unknown>;
|
|
6
|
+
export interface DocumentValidation extends ValidationResult {
|
|
7
|
+
expanded: Node[];
|
|
8
|
+
}
|
|
9
|
+
export declare const validateDocument: (document: unknown, base: string) => Promise<DocumentValidation>;
|
|
10
|
+
export declare const validateExample: (file: string) => Promise<ValidationResult>;
|
|
11
|
+
export declare const findExamples: (dir: string) => string[];
|
package/dist/validate.js
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { readFileSync, readdirSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { pathToFileURL } from "node:url";
|
|
4
|
+
import jsonld from "jsonld";
|
|
5
|
+
import { domainAlternatives, rangeAlternatives, declaredClasses, declaredTerms, isOwnedIri, isSubClassOf, loadOntology, typesOf, } from "./ontology.js";
|
|
6
|
+
import { fileDocumentLoader } from "./loader.js";
|
|
7
|
+
const members = (value) => value.flatMap((v) => ("@list" in v ? v["@list"] : [v]));
|
|
8
|
+
const nodesIn = (value) => members(value).filter((v) => !("@value" in v));
|
|
9
|
+
const collectIris = (node, found) => {
|
|
10
|
+
for (const [key, value] of Object.entries(node)) {
|
|
11
|
+
if (key === "@type")
|
|
12
|
+
value.forEach((t) => found.add(t));
|
|
13
|
+
else if (!key.startsWith("@")) {
|
|
14
|
+
found.add(key);
|
|
15
|
+
nodesIn(value).forEach((v) => collectIris(v, found));
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
const indexTypes = (node, types) => {
|
|
20
|
+
const id = node["@id"];
|
|
21
|
+
if (id && node["@type"]) {
|
|
22
|
+
const known = types.get(id) ?? new Set();
|
|
23
|
+
node["@type"].forEach((t) => known.add(t));
|
|
24
|
+
types.set(id, known);
|
|
25
|
+
}
|
|
26
|
+
for (const [key, value] of Object.entries(node)) {
|
|
27
|
+
if (!key.startsWith("@"))
|
|
28
|
+
nodesIn(value).forEach((v) => indexTypes(v, types));
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
const checkDomainRange = (store, node, types, errors) => {
|
|
32
|
+
const classes = declaredClasses(store);
|
|
33
|
+
const subject = node["@id"] ?? "_:blank";
|
|
34
|
+
const subjectTypes = [...(node["@type"] ?? types.get(subject) ?? [])];
|
|
35
|
+
const conforms = (nodeTypes, required) => nodeTypes.some((t) => classes.has(t) && isSubClassOf(store, t, required));
|
|
36
|
+
for (const [key, value] of Object.entries(node)) {
|
|
37
|
+
if (key.startsWith("@"))
|
|
38
|
+
continue;
|
|
39
|
+
for (const alternatives of domainAlternatives(store, key)) {
|
|
40
|
+
if (!alternatives.some((domain) => conforms(subjectTypes, domain))) {
|
|
41
|
+
errors.push(`${subject} uses ${key} but is not typed as ${alternatives.join(" or ")}, which is the domain of ${key}`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
for (const range of rangeAlternatives(store, key).filter((alternatives) => alternatives.every((r) => classes.has(r)))) {
|
|
45
|
+
for (const object of members(value)) {
|
|
46
|
+
const objectId = object["@id"];
|
|
47
|
+
const objectTypes = [
|
|
48
|
+
...(object["@type"] ?? (objectId && types.get(objectId)) ?? (objectId ? typesOf(store, objectId) : [])),
|
|
49
|
+
];
|
|
50
|
+
if (!range.some((alternative) => conforms(objectTypes, alternative))) {
|
|
51
|
+
const shown = objectTypes.length ? objectTypes.join(", ") : "untyped";
|
|
52
|
+
errors.push(`${subject} ${key} ${objectId ?? "_:blank"} has type ${shown}, which is not a ${range.join(" or ")}, the range of ${key}`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
nodesIn(value).forEach((v) => checkDomainRange(store, v, types, errors));
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
export const validateDocument = async (document, base) => {
|
|
60
|
+
const errors = [];
|
|
61
|
+
let expanded;
|
|
62
|
+
try {
|
|
63
|
+
expanded = await jsonld.expand(document, { base, documentLoader: fileDocumentLoader, safe: true });
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
return { valid: false, errors: [error instanceof Error ? error.message : String(error)], expanded: [] };
|
|
67
|
+
}
|
|
68
|
+
const store = loadOntology();
|
|
69
|
+
const declared = declaredTerms(store);
|
|
70
|
+
const used = new Set();
|
|
71
|
+
expanded.forEach((node) => collectIris(node, used));
|
|
72
|
+
for (const iri of used) {
|
|
73
|
+
if (isOwnedIri(iri) && !declared.has(iri))
|
|
74
|
+
errors.push(`${iri} is not declared in the ontology`);
|
|
75
|
+
}
|
|
76
|
+
const types = new Map();
|
|
77
|
+
expanded.forEach((node) => indexTypes(node, types));
|
|
78
|
+
expanded.forEach((node) => checkDomainRange(store, node, types, errors));
|
|
79
|
+
if (expanded.length === 0)
|
|
80
|
+
errors.push("document expands to no nodes");
|
|
81
|
+
return { valid: errors.length === 0, errors, expanded };
|
|
82
|
+
};
|
|
83
|
+
export const validateExample = async (file) => {
|
|
84
|
+
let document;
|
|
85
|
+
try {
|
|
86
|
+
document = JSON.parse(readFileSync(file, "utf8"));
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
return { valid: false, errors: [error instanceof Error ? error.message : String(error)] };
|
|
90
|
+
}
|
|
91
|
+
const { valid, errors } = await validateDocument(document, pathToFileURL(file).href);
|
|
92
|
+
return { valid, errors };
|
|
93
|
+
};
|
|
94
|
+
export const findExamples = (dir) => readdirSync(dir, { withFileTypes: true }).flatMap((entry) => entry.isDirectory() ? findExamples(join(dir, entry.name)) : entry.name.endsWith(".jsonld") ? [join(dir, entry.name)] : []);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { latestPointsTo, planPublication } from "./versioning.js";
|
|
2
|
+
const args = process.argv.slice(2);
|
|
3
|
+
const published = args
|
|
4
|
+
.filter((arg) => arg.startsWith("--published="))
|
|
5
|
+
.flatMap((arg) => arg.slice("--published=".length).split(",").filter(Boolean));
|
|
6
|
+
const [version] = args.filter((arg) => !arg.startsWith("--"));
|
|
7
|
+
if (!version) {
|
|
8
|
+
console.error("usage: npm run publish-layout -- <version> [--published=1.0.0,1.1.0]");
|
|
9
|
+
process.exit(2);
|
|
10
|
+
}
|
|
11
|
+
try {
|
|
12
|
+
const plan = planPublication(version, published);
|
|
13
|
+
console.log(JSON.stringify({ ...plan, updatesLatest: latestPointsTo(published, plan.version) }, null, 2));
|
|
14
|
+
}
|
|
15
|
+
catch (error) {
|
|
16
|
+
console.error(error.message);
|
|
17
|
+
process.exit(1);
|
|
18
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export declare const PUBLISH_BASE: string;
|
|
2
|
+
export declare const PUBLISHED_ARTIFACTS: readonly ["ontology/core.ttl", "ontology/di.ttl", "contexts/core.jsonld", "contexts/di.jsonld", "contexts/combined.jsonld", "shapes/core.shapes.ttl"];
|
|
3
|
+
export interface PublishedFile {
|
|
4
|
+
source: string;
|
|
5
|
+
versioned: string;
|
|
6
|
+
latest: string;
|
|
7
|
+
}
|
|
8
|
+
export interface PublicationPlan {
|
|
9
|
+
version: string;
|
|
10
|
+
tag: string;
|
|
11
|
+
files: PublishedFile[];
|
|
12
|
+
}
|
|
13
|
+
export declare const normalizeVersion: (input: string) => string;
|
|
14
|
+
export declare const compareVersions: (a: string, b: string) => number;
|
|
15
|
+
export declare const latestVersion: (versions: string[]) => string | undefined;
|
|
16
|
+
export declare const planPublication: (input: string, publishedVersions?: string[], artifacts?: readonly string[]) => PublicationPlan;
|
|
17
|
+
export declare const latestPointsTo: (publishedVersions: string[], candidate: string) => boolean;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { BPMN_NAMESPACE } from "./namespace.js";
|
|
2
|
+
export const PUBLISH_BASE = new URL(BPMN_NAMESPACE).origin;
|
|
3
|
+
export const PUBLISHED_ARTIFACTS = [
|
|
4
|
+
"ontology/core.ttl",
|
|
5
|
+
"ontology/di.ttl",
|
|
6
|
+
"contexts/core.jsonld",
|
|
7
|
+
"contexts/di.jsonld",
|
|
8
|
+
"contexts/combined.jsonld",
|
|
9
|
+
"shapes/core.shapes.ttl",
|
|
10
|
+
];
|
|
11
|
+
const SEMVER = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$/;
|
|
12
|
+
export const normalizeVersion = (input) => {
|
|
13
|
+
const version = input.startsWith("v") ? input.slice(1) : input;
|
|
14
|
+
if (!SEMVER.test(version))
|
|
15
|
+
throw new Error(`invalid semantic version: ${input}`);
|
|
16
|
+
return version;
|
|
17
|
+
};
|
|
18
|
+
export const compareVersions = (a, b) => {
|
|
19
|
+
const left = normalizeVersion(a).split(".").map(Number);
|
|
20
|
+
const right = normalizeVersion(b).split(".").map(Number);
|
|
21
|
+
for (let i = 0; i < 3; i++)
|
|
22
|
+
if (left[i] !== right[i])
|
|
23
|
+
return left[i] - right[i];
|
|
24
|
+
return 0;
|
|
25
|
+
};
|
|
26
|
+
export const latestVersion = (versions) => versions.length === 0 ? undefined : versions.map(normalizeVersion).sort(compareVersions).at(-1);
|
|
27
|
+
export const planPublication = (input, publishedVersions = [], artifacts = PUBLISHED_ARTIFACTS) => {
|
|
28
|
+
const version = normalizeVersion(input);
|
|
29
|
+
if (publishedVersions.some((published) => normalizeVersion(published) === version)) {
|
|
30
|
+
throw new Error(`version ${version} is already published and immutable`);
|
|
31
|
+
}
|
|
32
|
+
return {
|
|
33
|
+
version,
|
|
34
|
+
tag: `v${version}`,
|
|
35
|
+
files: artifacts.map((source) => ({
|
|
36
|
+
source,
|
|
37
|
+
versioned: `${PUBLISH_BASE}/v${version}/${source}`,
|
|
38
|
+
latest: `${PUBLISH_BASE}/latest/${source}`,
|
|
39
|
+
})),
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
export const latestPointsTo = (publishedVersions, candidate) => {
|
|
43
|
+
const newest = latestVersion([...publishedVersions, candidate]);
|
|
44
|
+
return newest === normalizeVersion(candidate);
|
|
45
|
+
};
|