From 923598c2446a5003fef01f5f2a0e5006fcf27093 Mon Sep 17 00:00:00 2001 From: paed01 Date: Thu, 29 Dec 2022 09:34:14 +0100 Subject: [PATCH 1/2] convert to module --- .eslintignore | 1 - .eslintrc.json | 2 +- .mocharc.js => .mocharc.cjs | 11 - CHANGELOG.md | 5 + README.md | 20 - dist/.eslintrc.json | 23 - dist/index.js | 987 ----------------------------- package.json | 28 +- test/backwardCompatibility-test.js | 45 +- test/deserialize-test.js | 6 +- test/edge-case-test.js | 6 +- test/helpers/factory.js | 5 +- test/helpers/testHelpers.js | 12 + test/io-test.js | 10 +- test/messageflow-test.js | 6 +- test/performance-test.js | 8 +- test/pools-and-lanes-test.js | 8 +- test/script-test.js | 10 +- test/sequence-flow-test.js | 9 +- test/serializer-test.js | 13 +- test/timer-test.js | 10 +- 21 files changed, 106 insertions(+), 1119 deletions(-) rename .mocharc.js => .mocharc.cjs (53%) delete mode 100644 dist/.eslintrc.json delete mode 100644 dist/index.js diff --git a/.eslintignore b/.eslintignore index 7265d83..99c1156 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,4 +1,3 @@ -.nyc_output coverage/ node_modules tmp/ diff --git a/.eslintrc.json b/.eslintrc.json index 4b415a0..2c7f171 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -2,7 +2,7 @@ "parser": "espree", "parserOptions": { "sourceType": "module", - "ecmaVersion": 2018 + "ecmaVersion": 2020 }, "env": { "es6": true, diff --git a/.mocharc.js b/.mocharc.cjs similarity index 53% rename from .mocharc.js rename to .mocharc.cjs index 9722da7..6d14b4d 100644 --- a/.mocharc.js +++ b/.mocharc.cjs @@ -4,19 +4,8 @@ process.env.NODE_ENV = 'test'; global.expect = require('chai').expect; - -require('@babel/register')({ - include: [ - '../index.js', - '../test/**', - '../node_modules/bpmn-moddle-5/**' - ], -}); - module.exports = { - exit: true, recursive: true, reporter: 'spec', timeout: 1000, }; - diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a6e6f4..0c8b465 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,11 @@ Changelog ========= +# 3.0.0 + +- Converted to module +- Remove backward compatibility test for bpmn-moddle@5 + # 2.2.0 - Add property `script.type` to added scripts diff --git a/README.md b/README.md index f9d14d7..1c4366f 100644 --- a/README.md +++ b/README.md @@ -31,23 +31,3 @@ function extender(behaviourMapping) { behaviourMapping['bpmn:EscalationEventDefinition'] = EscalationEventDefinition; } ``` - -## Backward compatibility - -In `bpmn-moddle@5` the moddle context is served in the third argument of the callback. It has a sligthly different scheme but is still supported. - -Promisified example of how to retrieive the moddle context: -```js -import BpmnModdle from 'bpmn-moddle'; - -function getModdleContext(source) { - const bpmnModdle = new BpmnModdle(); - - return new Promise((resolve, reject) => { - bpmnModdle.fromXML(source, (err, definitions, moddleContext) => { - if (err) return reject(err); - resolve(moddleContext); - }); - }); -} -``` diff --git a/dist/.eslintrc.json b/dist/.eslintrc.json deleted file mode 100644 index c60f36d..0000000 --- a/dist/.eslintrc.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "env": { - "node": true - }, - "parserOptions": { - "sourceType": "script", - "ecmaVersion": 2018 - }, - "rules": { - "arrow-parens": 0, - "comma-dangle": 0, - "curly": 0, - "brace-style": 0, - "eol-last": 0, - "indent": 0, - "no-var": 0, - "no-cond-assign": 0, - "quotes": 0, - "semi-spacing": 0, - "space-unary-ops": 0, - "space-before-function-paren": 0 - } -} diff --git a/dist/index.js b/dist/index.js deleted file mode 100644 index 8025bd4..0000000 --- a/dist/index.js +++ /dev/null @@ -1,987 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.TypeResolver = TypeResolver; -exports.default = void 0; -exports.deserialize = deserialize; -exports.map = mapModdleContext; -exports.resolveTypes = resolveTypes; -var _default = context; -exports.default = _default; -const refKeyPattern = /^(?!\$).+?Ref$/; -function TypeResolver(types, extender) { - const { - BpmnError, - Definition, - Dummy, - ServiceImplementation - } = types; - const typeMapper = {}; - typeMapper['bpmn:DataObjectReference'] = Dummy; - typeMapper['bpmn:Definitions'] = Definition; - typeMapper['bpmn:Error'] = BpmnError; - if (extender) extender(typeMapper); - return function resolve(entity) { - const { - type, - behaviour - } = entity; - entity.Behaviour = getBehaviourFromType(type); - if (!behaviour) return; - if (behaviour.implementation) { - behaviour.Service = ServiceImplementation; - } - if (behaviour.loopCharacteristics) { - resolve(behaviour.loopCharacteristics); - } - if (behaviour.eventDefinitions) { - for (const ed of behaviour.eventDefinitions) { - resolve(ed); - } - } - if (behaviour.ioSpecification) { - resolve(behaviour.ioSpecification); - } - if (behaviour.properties) { - behaviour.properties.Behaviour = types.Properties; - } - }; - function getBehaviourFromType(type) { - let activityType = typeMapper[type]; - if (!activityType && type) { - const nonPrefixedType = type.split(':').slice(1).join(':'); - activityType = types[nonPrefixedType]; - } - if (!activityType) { - throw new Error(`Unknown activity type ${type}`); - } - return activityType; - } -} -function mapModdleContext(moddleContext, extendFn) { - return new Mapper(moddleContext, extendFn).map(); -} -function context(moddleContext, typeResolver, extendFn) { - const mapped = new Mapper(moddleContext, extendFn).map(); - return new ContextApi(resolveTypes(mapped, typeResolver)); -} -function deserialize(deserializedContext, typeResolver) { - return new ContextApi(resolveTypes(deserializedContext, typeResolver)); -} -function ContextApi(elements) { - const definition = elements.definition; - this.id = definition.id; - this.type = definition.type; - this.name = definition.name; - elements.dataStores = elements.dataStores || []; - elements.scripts = elements.scripts || []; - elements.timers = elements.timers || []; - this.elements = elements; -} -ContextApi.prototype.serialize = function serialize() { - const elements = this.elements; - return JSON.stringify({ - id: elements.definition.id, - type: elements.definition.type, - name: elements.definition.name, - ...elements - }); -}; -ContextApi.prototype.getProcessById = function getProcessById(processId) { - return this.elements.processes.find(({ - id - }) => id === processId); -}; -ContextApi.prototype.getProcesses = function getProcesses() { - return this.elements.processes; -}; -ContextApi.prototype.getExecutableProcesses = function getExecutableProcesses() { - return this.elements.processes.filter(p => p.behaviour.isExecutable); -}; -ContextApi.prototype.getInboundSequenceFlows = function getInboundSequenceFlows(activityId) { - return this.elements.sequenceFlows.filter(flow => flow.targetId === activityId); -}; -ContextApi.prototype.getOutboundSequenceFlows = function getOutboundSequenceFlows(activityId) { - return this.elements.sequenceFlows.filter(flow => flow.sourceId === activityId); -}; -ContextApi.prototype.getMessageFlows = function getMessageFlows(scopeId) { - const messageFlows = this.elements.messageFlows; - if (scopeId) return messageFlows.filter(flow => flow.source.processId === scopeId); - return messageFlows; -}; -ContextApi.prototype.getSequenceFlows = function getSequenceFlows(scopeId) { - const sequenceFlows = this.elements.sequenceFlows; - if (scopeId) return sequenceFlows.filter(flow => flow.parent.id === scopeId); - return sequenceFlows; -}; -ContextApi.prototype.getSequenceFlowById = function getSequenceFlowById(flowId) { - return this.elements.sequenceFlows.find(({ - id - }) => id === flowId); -}; -ContextApi.prototype.getActivities = function getActivities(scopeId) { - const activities = this.elements.activities; - if (!scopeId) return activities; - return activities.filter(activity => activity.parent.id === scopeId); -}; -ContextApi.prototype.getDataObjects = function getDataObjects(scopeId) { - if (!scopeId) return this.elements.dataObjects; - return this.elements.dataObjects.filter(elm => elm.parent.id === scopeId); -}; -ContextApi.prototype.getDataStoreReferences = function getDataStoreReferences(scopeId) { - if (!scopeId) return this.elements.dataStores; - return this.elements.dataStores.filter(elm => elm.parent.id === scopeId); -}; -ContextApi.prototype.getDataObjectById = function getDataObjectById(dataObjectId) { - return this.elements.dataObjects.find(({ - id - }) => id === dataObjectId); -}; -ContextApi.prototype.getDataStoreReferenceById = function getDataStoreReferenceById(dataStoreId) { - return this.elements.dataStores.find(({ - id - }) => id === dataStoreId); -}; -ContextApi.prototype.getDataStores = function getDataStores() { - return this.elements.dataStores.filter(({ - type - }) => type === 'bpmn:DataStore'); -}; -ContextApi.prototype.getDataStoreById = function getDataStoreById(dataStoreId) { - return this.elements.dataStores.find(({ - id, - type - }) => id === dataStoreId && type === 'bpmn:DataStore'); -}; -ContextApi.prototype.getActivityById = function getActivityById(activityId) { - return this.elements.activities.find(activity => activity.id === activityId); -}; -ContextApi.prototype.getAssociations = function getAssociations(scopeId) { - const associations = this.elements.associations; - if (scopeId) return associations.filter(flow => flow.parent.id === scopeId); - return associations; -}; -ContextApi.prototype.getAssociationById = function getAssociationById(associationId) { - return this.elements.associations.find(association => association.id === associationId); -}; -ContextApi.prototype.getExtendContext = function getExtendContext() { - return new ExtendContext({ - scripts: this.elements.scripts, - timers: this.elements.timers - }); -}; -ContextApi.prototype.getInboundAssociations = function getInboundAssociations(activityId) { - return this.elements.associations.filter(flow => flow.targetId === activityId); -}; -ContextApi.prototype.getOutboundAssociations = function getOutboundAssociations(activityId) { - return this.elements.associations.filter(flow => flow.sourceId === activityId); -}; -ContextApi.prototype.getScripts = function getScripts(elementType) { - const scripts = this.elements.scripts; - if (!elementType) return scripts.slice(); - return scripts.filter(({ - parent - }) => parent.type === elementType); -}; -ContextApi.prototype.getScriptsByElementId = function getScriptsByElementId(elementId) { - return this.elements.scripts.filter(({ - parent - }) => parent.id === elementId); -}; -ContextApi.prototype.getTimers = function getTimers(elementType) { - const timers = this.elements.timers; - if (!elementType) return timers.slice(); - return timers.filter(({ - parent - }) => parent.type === elementType); -}; -ContextApi.prototype.getTimersByElementId = function getTimersByElementId(elementId) { - return this.elements.timers.filter(({ - parent - }) => parent.id === elementId); -}; -function resolveTypes(mappedContext, typeResolver) { - const { - activities, - associations, - dataObjects, - dataStores = [], - definition, - messageFlows, - processes, - sequenceFlows - } = mappedContext; - definition.Behaviour = typeResolver(definition); - processes.forEach(typeResolver); - activities.forEach(typeResolver); - dataObjects.forEach(typeResolver); - dataStores.forEach(typeResolver); - messageFlows.forEach(typeResolver); - sequenceFlows.forEach(typeResolver); - associations.forEach(typeResolver); - return mappedContext; -} -function Mapper(moddleContext, extendFn) { - this.moddleContext = moddleContext; - this._extendFn = extendFn; - this.scripts = []; - this.timers = []; -} -Mapper.prototype.map = function map() { - const moddleContext = this.moddleContext; - const rootElement = this._root = moddleContext.rootElement ? moddleContext.rootElement : moddleContext.rootHandler.element; - const definition = { - id: rootElement.id, - type: rootElement.$type, - name: rootElement.name, - targetNamespace: rootElement.targetNamespace, - exporter: rootElement.exporter, - exporterVersion: rootElement.exporterVersion - }; - this._references = this._prepareReferences(); - const elements = this._prepareElements(definition, rootElement.rootElements); - return { - definition, - ...elements, - scripts: this.scripts, - timers: this.timers - }; -}; -Mapper.prototype._prepareReferences = function prepareReferences() { - const result = { - dataInputAssociations: [], - dataObjectRefs: [], - dataOutputAssociations: [], - dataStoreRefs: [], - flowNodeRefs: {}, - flowRefs: {}, - processRefs: {}, - sourceRefs: {}, - targetRefs: {} - }; - const { - references, - elementsById - } = this.moddleContext; - for (const r of references) { - const { - property, - element - } = r; - switch (property) { - case 'bpmn:sourceRef': - { - const flow = this._upsertRef(result.flowRefs, element.id, { - id: element.id, - $type: element.$type, - sourceId: r.id, - element: elementsById[element.id] - }); - const outbound = result.sourceRefs[r.id] = result.sourceRefs[r.id] || []; - outbound.push(flow); - break; - } - case 'bpmn:targetRef': - { - const flow = this._upsertRef(result.flowRefs, element.id, { - targetId: r.id - }); - const inbound = result.targetRefs[r.id] = result.targetRefs[r.id] || []; - inbound.push(flow); - break; - } - case 'bpmn:default': - this._upsertRef(result.flowRefs, r.id, { - isDefault: true - }); - break; - case 'bpmn:dataStoreRef': - result.dataStoreRefs.push(r); - break; - case 'bpmn:dataObjectRef': - result.dataObjectRefs.push(r); - break; - case 'bpmn:processRef': - { - result.processRefs[element.id] = { - id: r.id, - $type: element.$type - }; - break; - } - case 'bpmn:flowNodeRef': - result.flowNodeRefs[r.id] = { - ...element - }; - break; - } - switch (element.$type) { - case 'bpmn:DataInputAssociation': - result.dataInputAssociations.push(r); - break; - case 'bpmn:DataOutputAssociation': - result.dataOutputAssociations.push(r); - break; - } - } - return result; -}; -Mapper.prototype._upsertRef = function upsertFlowRef(target, id, value) { - const flow = target[id] = target[id] || {}; - Object.assign(flow, value); - return flow; -}; -Mapper.prototype._prepareElements = function prepareElements(parent, elements) { - const result = { - activities: [], - associations: [], - dataObjects: [], - dataStores: [], - messageFlows: [], - participants: [], - processes: [], - sequenceFlows: [] - }; - if (!elements) return result; - const references = this._references; - for (const element of elements) { - const { - id, - $type: type, - name - } = element; - switch (type) { - case 'bpmn:DataObjectReference': - break; - case 'bpmn:Collaboration': - { - if (element.messageFlows) { - const { - messageFlows: flows - } = this._prepareElements(parent, element.messageFlows); - result.messageFlows = result.messageFlows.concat(flows); - } - if (element.participants) { - for (const p of element.participants) { - const processRef = references.processRefs[p.id]; - result.participants.push({ - id: p.id, - type: p.$type, - name: p.name, - processId: processRef && processRef.id, - parent: { - id, - type - } - }); - } - } - break; - } - case 'bpmn:DataObject': - { - result.dataObjects.push({ - id, - name, - type, - parent: { - id: parent.id, - type: parent.type - }, - references: this._prepareDataObjectReferences(element), - behaviour: this._prepareElementBehaviour(element) - }); - break; - } - case 'bpmn:DataStore': - { - result.dataStores.push({ - id, - name, - type, - parent: { - id: parent.id, - type: parent.type - }, - references: this._prepareDataStoreReferences(element), - behaviour: this._prepareElementBehaviour(element) - }); - break; - } - case 'bpmn:DataStoreReference': - { - result.dataStores.push({ - id, - name, - type, - parent: { - id: parent.id, - type: parent.type - }, - behaviour: this._prepareElementBehaviour(element) - }); - break; - } - case 'bpmn:MessageFlow': - { - const flowRef = references.flowRefs[element.id]; - result.messageFlows.push({ - ...flowRef, - id, - type, - name, - parent: { - id: parent.id, - type: parent.type - }, - ...this._getMessageFlowSourceAndTarget(flowRef), - behaviour: this._prepareElementBehaviour(element) - }); - break; - } - case 'bpmn:Association': - { - const flowRef = references.flowRefs[element.id]; - result.associations.push({ - id, - name, - type, - parent: { - id: parent.id, - type: parent.type - }, - targetId: flowRef.targetId, - sourceId: flowRef.sourceId, - behaviour: this._prepareElementBehaviour(element) - }); - break; - } - case 'bpmn:SequenceFlow': - { - const flowRef = references.flowRefs[element.id]; - result.sequenceFlows.push({ - id, - name, - type, - parent: { - id: parent.id, - type: parent.type - }, - isDefault: flowRef.isDefault, - targetId: flowRef.targetId, - sourceId: flowRef.sourceId, - behaviour: this._prepareElementBehaviour(element) - }); - break; - } - case 'bpmn:SubProcess': - case 'bpmn:Transaction': - case 'bpmn:Process': - { - const bp = { - id, - type, - name, - parent: { - id: parent.id, - type: parent.type - }, - behaviour: this._prepareElementBehaviour(element) - }; - if (type === 'bpmn:Process') result.processes.push(bp);else result.activities.push(bp); - for (const subElements of [this._prepareElements(bp, element.flowElements), this._prepareElements(bp, element.artifacts)]) { - result.activities = result.activities.concat(subElements.activities); - result.sequenceFlows = result.sequenceFlows.concat(subElements.sequenceFlows); - result.dataObjects = result.dataObjects.concat(subElements.dataObjects); - result.dataStores = result.dataStores.concat(subElements.dataStores); - result.associations = result.associations.concat(subElements.associations); - } - break; - } - case 'bpmn:BoundaryEvent': - { - const attachedTo = element.attachedToRef && spreadRef(element.attachedToRef); - result.activities.push(this._prepareActivity(element, parent, { - attachedTo - })); - break; - } - case 'bpmn:ScriptTask': - { - const { - scriptFormat, - script, - resource - } = element; - new ExtendContext({ - scripts: this.scripts - }).addScript(element.id, { - parent: { - id, - type - }, - scriptFormat, - ...(script && { - body: script - }), - ...(resource && { - resource - }), - type: 'bpmn:Script' - }); - result.activities.push(this._prepareActivity(element, parent)); - break; - } - default: - { - result.activities.push(this._prepareActivity(element, parent)); - } - } - } - return result; -}; -Mapper.prototype._prepareActivity = function prepareActivity(element, parent, behaviour) { - const { - id, - $type: type, - name - } = element; - const lane = this._references.flowNodeRefs[id]; - return { - id, - type, - name, - parent: { - id: parent.id, - type: parent.type - }, - ...(lane && { - lane: { - ...lane - } - }), - behaviour: this._prepareElementBehaviour(element, behaviour) - }; -}; -Mapper.prototype._prepareElementBehaviour = function prepareElementBehaviour(element, behaviour) { - const { - id, - $type: type, - eventDefinitions, - loopCharacteristics, - ioSpecification, - conditionExpression, - properties - } = element; - const preparedElement = { - ...behaviour, - ...element, - ...(eventDefinitions && { - eventDefinitions - }) - }; - const extendContext = new ExtendContext({ - scripts: this.scripts, - timers: this.timers, - parent: { - id, - type - } - }); - if (eventDefinitions) { - const definitions = preparedElement.eventDefinitions = []; - for (const ed of eventDefinitions) { - const edBehaviour = this._mapActivityBehaviour(ed, extendContext); - if (edBehaviour) definitions.push(edBehaviour); - } - } - if (loopCharacteristics) { - preparedElement.loopCharacteristics = this._mapActivityBehaviour(loopCharacteristics, extendContext); - } - if (properties) { - const props = preparedElement.properties = { - type: 'properties', - values: [] - }; - for (const prop of properties) { - props.values.push(this._mapActivityBehaviour(prop, extendContext)); - } - } - if (ioSpecification) { - preparedElement.ioSpecification = this._mapActivityBehaviour(ioSpecification, extendContext); - } - if (element.dataInputAssociations) { - const associations = preparedElement.dataInputAssociations = []; - for (const association of element.dataInputAssociations) { - associations.push(this._mapActivityBehaviour(association, extendContext)); - } - } - if (element.dataOutputAssociations) { - const associations = preparedElement.dataOutputAssociations = []; - for (const association of element.dataOutputAssociations) { - associations.push(this._mapActivityBehaviour(association, extendContext)); - } - } - if (conditionExpression && conditionExpression.language) { - const { - $type: exprType, - language: scriptFormat, - ...rest - } = conditionExpression; - extendContext.addScript(id, { - type: exprType, - scriptFormat, - ...rest - }); - } - if (element.resources) { - const resources = preparedElement.resources = []; - for (const resource of element.resources) { - const { - $type, - resourceAssignmentExpression - } = resource; - resources.push({ - type: $type, - expression: resourceAssignmentExpression.expression && resourceAssignmentExpression.expression.body, - behaviour: { - ...resource - } - }); - } - } - if (element.messageRef) { - preparedElement.messageRef = spreadRef(element.messageRef); - } - const extendFn = this._extendFn; - if (!extendFn) return preparedElement; - const mod = extendFn(preparedElement, extendContext); - return { - ...mod, - ...preparedElement - }; -}; -Mapper.prototype._mapActivityBehaviour = function mapActivityBehaviour(ed, extendContext) { - if (!ed) return; - const { - $type: type, - id - } = ed; - let behaviour = { - ...ed - }; - const keys = Object.getOwnPropertyNames(ed); - for (const key of keys) { - if (refKeyPattern.test(key)) behaviour[key] = spreadRef(ed[key]); - } - switch (type) { - case 'bpmn:ConditionalEventDefinition': - { - behaviour.expression = behaviour.condition && behaviour.condition.body; - break; - } - case 'bpmn:InputOutputSpecification': - { - behaviour = this._prepareIoSpecificationBehaviour(ed); - break; - } - case 'bpmn:Property': - { - behaviour = this._preparePropertyBehaviour(ed); - break; - } - case 'bpmn:MultiInstanceLoopCharacteristics': - { - behaviour.loopCardinality = ed.loopCardinality && ed.loopCardinality.body; - behaviour.completionCondition = ed.completionCondition && ed.completionCondition.body; - break; - } - case 'bpmn:StandardLoopCharacteristics': - { - behaviour.loopCondition = ed.loopCondition && ed.loopCondition.body; - break; - } - case 'bpmn:TimerEventDefinition': - { - for (const timerType of ['timeCycle', 'timeDuration', 'timeDate']) { - if (timerType in behaviour && behaviour[timerType].body) { - const value = behaviour[timerType] = behaviour[timerType].body; - extendContext.addTimer(id || timerType, { - id, - type, - timerType, - value - }); - } - } - break; - } - case 'bpmn:DataOutputAssociation': - case 'bpmn:DataInputAssociation': - { - if (Array.isArray(ed.sourceRef) && ed.sourceRef.length) { - behaviour.sourceRef = spreadRef(ed.sourceRef[0]); - } - break; - } - } - return { - id, - type, - behaviour - }; -}; -Mapper.prototype._preparePropertyBehaviour = function preparePropertyBehaviour(propertyDef) { - const dataInput = this._getDataInputBehaviour(propertyDef.id); - const dataOutput = this._getDataOutputBehaviour(propertyDef.id); - return { - ...propertyDef, - ...(dataInput.association.source && { - dataInput - }), - ...(dataOutput.association.target && { - dataOutput - }) - }; -}; -Mapper.prototype._prepareIoSpecificationBehaviour = function prepareIoSpecificationBehaviour({ - dataInputs, - dataOutputs -}) { - const result = {}; - if (dataInputs) { - result.dataInputs = []; - for (const input of dataInputs) { - result.dataInputs.push({ - ...input, - type: input.$type, - behaviour: this._getDataInputBehaviour(input.id) - }); - } - } - if (dataOutputs) { - result.dataOutputs = []; - for (const output of dataOutputs) { - result.dataOutputs.push({ - ...output, - type: output.$type, - behaviour: this._getDataOutputBehaviour(output.id) - }); - } - } - return result; -}; -Mapper.prototype._prepareDataStoreReferences = function prepareDataStoreReferences(element) { - const objectRefs = this._references.dataStoreRefs.filter(objectRef => objectRef.id === element.id); - return objectRefs.map(objectRef => { - return { - id: objectRef.element.id, - type: objectRef.element.$type, - behaviour: { - ...objectRef.element - } - }; - }); -}; -Mapper.prototype._getDataInputBehaviour = function getDataInputBehaviour(dataInputId) { - const dataInputAssociations = this._references.dataInputAssociations; - const target = dataInputAssociations.find(assoc => assoc.property === 'bpmn:targetRef' && assoc.id === dataInputId && assoc.element); - const source = target && dataInputAssociations.find(assoc => assoc.property === 'bpmn:sourceRef' && assoc.element && assoc.element.id === target.element.id); - return { - association: { - source: source && { - ...source, - ...this._getDataRef(source.id) - }, - target: target && { - ...target - } - } - }; -}; -Mapper.prototype._getDataOutputBehaviour = function getDataOutputBehaviour(dataOutputId) { - const dataOutputAssociations = this._references.dataOutputAssociations; - const source = dataOutputAssociations.find(assoc => assoc.property === 'bpmn:sourceRef' && assoc.id === dataOutputId && assoc.element); - const target = source && dataOutputAssociations.find(assoc => assoc.property === 'bpmn:targetRef' && assoc.element && assoc.element.id === source.element.id); - return { - association: { - source: source && { - ...source - }, - target: target && { - ...target, - ...this._getDataRef(target.id) - } - } - }; -}; -Mapper.prototype._getDataRef = function getDataRef(referenceId) { - const dataObject = this._getDataObject(referenceId); - const dataStore = this._getDataStore(referenceId); - return { - ...(dataObject && { - dataObject - }), - ...(dataStore && { - dataStore - }) - }; -}; -Mapper.prototype._getDataObject = function getDataObject(referenceId) { - const dataReference = this._references.dataObjectRefs.find(dor => dor.element && dor.element.id === referenceId); - if (!dataReference) { - const dataElm = this.moddleContext.elementsById[referenceId]; - return dataElm && dataElm.$type === 'bpmn:DataObject' && { - ...dataElm - }; - } - return { - ...this.moddleContext.elementsById[dataReference.id] - }; -}; -Mapper.prototype._getDataStore = function getDataStore(referenceId) { - const dataReference = this._references.dataStoreRefs.find(dor => dor.element && dor.element.id === referenceId); - if (dataReference) return { - ...this.moddleContext.elementsById[dataReference.id] - }; - const dataElm = this.moddleContext.elementsById[referenceId]; - if (!dataElm) return; - switch (dataElm.$type) { - case 'bpmn:DataStore': - case 'bpmn:DataStoreReference': - return { - ...dataElm - }; - } -}; -Mapper.prototype._prepareDataObjectReferences = function prepareDataObjectReferences(element) { - const objectRefs = this._references.dataObjectRefs.filter(objectRef => objectRef.id === element.id); - return objectRefs.map(objectRef => { - return { - id: objectRef.element.id, - type: objectRef.element.$type, - behaviour: { - ...objectRef.element - } - }; - }); -}; -Mapper.prototype._getMessageFlowSourceAndTarget = function getMessageFlowSourceAndTarget(flowRef) { - return { - source: this._getElementRef(flowRef.sourceId), - target: this._getElementRef(flowRef.targetId) - }; -}; -Mapper.prototype._getElementRef = function getElementRef(elementId) { - const targetElement = this.moddleContext.elementsById[elementId]; - if (!targetElement) return; - const result = {}; - switch (targetElement.$type) { - case 'bpmn:Participant': - { - result.processId = this._references.processRefs[elementId].id; - result.participantId = targetElement.id; - result.participantName = targetElement.name; - break; - } - case 'bpmn:Process': - { - result.processId = targetElement.id; - break; - } - default: - { - const bp = this._root.rootElements.find(e => e.$type === 'bpmn:Process' && e.flowElements.find(ce => ce.id === elementId)); - result.processId = bp.id; - result.id = elementId; - } - } - return result; -}; -function ExtendContext({ - scripts, - timers = [], - parent -}) { - this.scripts = scripts; - this.timers = timers; - this._parent = parent; -} -ExtendContext.prototype.addScript = function addScript(scriptName, elm) { - const { - id, - scriptFormat, - body, - resource, - type, - parent - } = elm; - this.scripts.push({ - ...this._prepare(scriptName, parent || this._parent), - script: { - ...(id && { - id - }), - scriptFormat, - ...(body && { - body - }), - ...(resource && { - resource - }), - ...(type && { - type - }) - } - }); -}; -ExtendContext.prototype.addTimer = function addTimer(timerName, { - id, - timerType, - type, - value, - parent -}) { - this.timers.push({ - ...this._prepare(timerName, parent || this._parent), - timer: { - ...(id && { - id - }), - timerType, - ...(value && { - value - }), - ...(type && { - type - }) - } - }); -}; -ExtendContext.prototype._prepare = function prepare(name, { - id, - type -} = {}) { - return { - name, - ...(id && type && { - parent: { - id, - type - } - }) - }; -}; -function spreadRef({ - id, - $type: type, - name -}) { - return { - id, - type, - name - }; -} \ No newline at end of file diff --git a/package.json b/package.json index 96034ca..6624c8f 100644 --- a/package.json +++ b/package.json @@ -1,17 +1,14 @@ { "name": "moddle-context-serializer", - "version": "2.2.0", + "version": "3.0.0", "description": "Make bpmn-moddle context serializable and mapped to behaviour functions", - "module": "index.js", - "main": "dist/index.js", + "type": "module", "sideEffects": false, "scripts": { "test": "mocha", - "posttest": "npm run dist && eslint . --cache", - "prepare": "npm run dist", - "dist": "babel index.js -d dist", - "test:lcov": "nyc mocha -R dot && nyc report --reporter lcov && npm run posttest", - "cov:html": "nyc mocha -R dot && nyc report --reporter html" + "posttest": "eslint . --cache", + "test:lcov": "c8 -r lcov mocha && npm run posttest", + "cov:html": "c8 -r html -r text mocha" }, "repository": { "type": "git", @@ -22,7 +19,6 @@ "url": "https://github.com/paed01" }, "files": [ - "dist/index.js", "index.js" ], "license": "MIT", @@ -34,21 +30,17 @@ "isomorphic" ], "peerDependencies": { - "bpmn-moddle": ">=5" + "bpmn-moddle": ">=6" }, "devDependencies": { - "@babel/cli": "^7.20.7", - "@babel/core": "^7.20.7", - "@babel/preset-env": "^7.20.2", - "@babel/register": "^7.18.9", - "bpmn-moddle": "^7.1.2", - "bpmn-moddle-5": "npm:bpmn-moddle@5", + "bpmn-moddle": "^8.0.0", "bpmn-moddle-6": "npm:bpmn-moddle@6", + "bpmn-moddle-7": "npm:bpmn-moddle@7", + "c8": "^7.12.0", "camunda-bpmn-moddle": "^7.0.1", "camunda-bpmn-moddle-6": "npm:camunda-bpmn-moddle@6", "chai": "^4.3.7", "eslint": "^8.30.0", - "mocha": "^10.2.0", - "nyc": "^15.1.0" + "mocha": "^10.2.0" } } diff --git a/test/backwardCompatibility-test.js b/test/backwardCompatibility-test.js index 53a120d..e6f9d85 100644 --- a/test/backwardCompatibility-test.js +++ b/test/backwardCompatibility-test.js @@ -1,20 +1,20 @@ -import factory from './helpers/factory'; -import types from './helpers/types'; -import BpmnModdle5 from 'bpmn-moddle-5'; +import factory from './helpers/factory.js'; +import types from './helpers/types.js'; import BpmnModdle6 from 'bpmn-moddle-6'; -import testHelpers from './helpers/testHelpers'; +import BpmnModdle7 from 'bpmn-moddle-7'; +import testHelpers from './helpers/testHelpers.js'; -import {default as Serializer, TypeResolver, deserialize} from '../index'; +import {default as Serializer, TypeResolver, deserialize} from '../index.js'; const typeResolver = TypeResolver(types); describe('backward compatibility', () => { - describe('bpmn-moddle@5', () => { + describe('bpmn-moddle@6', () => { let moddleContext; before('load context', async () => { const source = factory.userTask(); moddleContext = await new Promise((resolve, reject) => { - const bpmnModdle = new BpmnModdle5(); + const bpmnModdle = new BpmnModdle6(); return bpmnModdle.fromXML(source, (err, definitions, ctx) => { if (err) return reject(err); resolve(ctx); @@ -30,17 +30,12 @@ describe('backward compatibility', () => { }); }); - describe('bpmn-moddle@6', () => { + describe('bpmn-moddle@7', () => { let moddleContext; before('load context', async () => { const source = factory.userTask(); - moddleContext = await new Promise((resolve, reject) => { - const bpmnModdle = new BpmnModdle6(); - return bpmnModdle.fromXML(source, (err, definitions, ctx) => { - if (err) return reject(err); - resolve(ctx); - }); - }); + const bpmnModdle = new BpmnModdle7(); + moddleContext = await bpmnModdle.fromXML(source); }); it('returns processes', () => { @@ -51,6 +46,26 @@ describe('backward compatibility', () => { }); }); + describe('camunda-bpmn-moddle@6', () => { + let moddleContext, moddleContext6; + before('load context', async () => { + const source = factory.resource('scripts.bpmn'); + moddleContext = await testHelpers.moddleContext(source, { + camunda: testHelpers.getCamundaExtension(), + }); + moddleContext6 = await testHelpers.moddleContext(source, { + camunda: testHelpers.getCamundaExtension('camunda-bpmn-moddle-6'), + }); + }); + + it('returns the same serialized context as latest version', () => { + const serializer = Serializer(moddleContext, typeResolver); + const serializer6 = Serializer(moddleContext6, typeResolver); + + expect(serializer.serialize()).to.equal(serializer6.serialize()); + }); + }); + describe('version without dataStores', async () => { it('handles missing dataStores property', async () => { const source = ` diff --git a/test/deserialize-test.js b/test/deserialize-test.js index bba02fb..f2b6aa9 100644 --- a/test/deserialize-test.js +++ b/test/deserialize-test.js @@ -1,7 +1,7 @@ -import testHelpers from './helpers/testHelpers'; -import types from './helpers/types'; +import testHelpers from './helpers/testHelpers.js'; +import types from './helpers/types.js'; -import {default as Serializer, TypeResolver, deserialize} from '../index'; +import {default as Serializer, TypeResolver, deserialize} from '../index.js'; const typeResolver = TypeResolver(types); diff --git a/test/edge-case-test.js b/test/edge-case-test.js index dd29ff5..01aace3 100644 --- a/test/edge-case-test.js +++ b/test/edge-case-test.js @@ -1,7 +1,7 @@ -import testHelpers from './helpers/testHelpers'; -import types from './helpers/types'; +import testHelpers from './helpers/testHelpers.js'; +import types from './helpers/types.js'; -import {default as Serializer, TypeResolver} from '../index'; +import {default as Serializer, TypeResolver} from '../index.js'; const typeResolver = TypeResolver(types); diff --git a/test/helpers/factory.js b/test/helpers/factory.js index 55c887e..f92b570 100644 --- a/test/helpers/factory.js +++ b/test/helpers/factory.js @@ -1,6 +1,9 @@ import BpmnModdle from 'bpmn-moddle'; import fs from 'fs'; import path from 'path'; +import {fileURLToPath} from 'url'; + +const dirname = fileURLToPath(new URL('.', import.meta.url)); const eventActivities = [ 'bpmn:IntermediateCatchEvent', @@ -121,7 +124,7 @@ function multipleInbound() { } function resource(name) { - return fs.readFileSync(path.join(__dirname, '..', 'resources', name)); + return fs.readFileSync(path.join(dirname, '..', 'resources', name)); } async function create(activityType) { diff --git a/test/helpers/testHelpers.js b/test/helpers/testHelpers.js index ffdedd3..b17e7c6 100644 --- a/test/helpers/testHelpers.js +++ b/test/helpers/testHelpers.js @@ -1,10 +1,22 @@ import BpmnModdle from 'bpmn-moddle'; +import fs from 'fs'; + +const camundaExtensions = {}; export default { moddleContext, + getCamundaExtension, }; function moddleContext(source, options) { const bpmnModdle = new BpmnModdle(options); return bpmnModdle.fromXML(Buffer.isBuffer(source) ? source.toString() : source.trim()); } + +function getCamundaExtension(version = 'camunda-bpmn-moddle') { + let content = camundaExtensions[version]; + if (!content) { + content = camundaExtensions[version] = fs.readFileSync(`./node_modules/${version}/resources/camunda.json`); + } + return JSON.parse(content); +} diff --git a/test/io-test.js b/test/io-test.js index bca570b..091d4ef 100644 --- a/test/io-test.js +++ b/test/io-test.js @@ -1,11 +1,11 @@ -import factory from './helpers/factory'; -import testHelpers from './helpers/testHelpers'; -import types from './helpers/types'; -import camunda from 'camunda-bpmn-moddle/resources/camunda'; +import factory from './helpers/factory.js'; +import testHelpers from './helpers/testHelpers.js'; +import types from './helpers/types.js'; -import {default as Serializer, TypeResolver, deserialize} from '../index'; +import {default as Serializer, TypeResolver, deserialize} from '../index.js'; const typeResolver = TypeResolver(types); +const camunda = testHelpers.getCamundaExtension(); describe('io', () => { describe('dataStoreReference', () => { diff --git a/test/messageflow-test.js b/test/messageflow-test.js index ce19773..7dbc0a3 100644 --- a/test/messageflow-test.js +++ b/test/messageflow-test.js @@ -1,7 +1,7 @@ -import testHelpers from './helpers/testHelpers'; -import types from './helpers/types'; +import testHelpers from './helpers/testHelpers.js'; +import types from './helpers/types.js'; -import {default as Serializer, TypeResolver, deserialize} from '../index'; +import {default as Serializer, TypeResolver, deserialize} from '../index.js'; const typeResolver = TypeResolver(types); diff --git a/test/performance-test.js b/test/performance-test.js index 6e0bc57..aca270f 100644 --- a/test/performance-test.js +++ b/test/performance-test.js @@ -1,8 +1,8 @@ -import factory from './helpers/factory'; -import testHelpers from './helpers/testHelpers'; -import types from './helpers/types'; +import factory from './helpers/factory.js'; +import testHelpers from './helpers/testHelpers.js'; +import types from './helpers/types.js'; -import {default as Serializer, TypeResolver} from '../index'; +import {default as Serializer, TypeResolver} from '../index.js'; const typeResolver = TypeResolver(types); const largeSource = factory.resource('nested-joins.bpmn'); diff --git a/test/pools-and-lanes-test.js b/test/pools-and-lanes-test.js index 161190d..e5173df 100644 --- a/test/pools-and-lanes-test.js +++ b/test/pools-and-lanes-test.js @@ -1,8 +1,8 @@ -import factory from './helpers/factory'; -import testHelpers from './helpers/testHelpers'; -import types from './helpers/types'; +import factory from './helpers/factory.js'; +import testHelpers from './helpers/testHelpers.js'; +import types from './helpers/types.js'; -import {default as Serializer, TypeResolver, deserialize} from '../index'; +import {default as Serializer, TypeResolver, deserialize} from '../index.js'; const typeResolver = TypeResolver(types); const lanesSource = factory.resource('lane-set.bpmn'); diff --git a/test/script-test.js b/test/script-test.js index 84c76a7..300fb3e 100644 --- a/test/script-test.js +++ b/test/script-test.js @@ -1,11 +1,11 @@ -import factory from './helpers/factory'; -import testHelpers from './helpers/testHelpers'; -import types from './helpers/types'; -import camunda from 'camunda-bpmn-moddle/resources/camunda'; +import factory from './helpers/factory.js'; +import testHelpers from './helpers/testHelpers.js'; +import types from './helpers/types.js'; -import {default as Serializer, TypeResolver, deserialize} from '../index'; +import {default as Serializer, TypeResolver, deserialize} from '../index.js'; const typeResolver = TypeResolver(types); +const camunda = testHelpers.getCamundaExtension(); describe('scripts', () => { describe('a process with inline, extension elements with scripts, extension external resource, and flow condition scripts, and a flow expression', () => { diff --git a/test/sequence-flow-test.js b/test/sequence-flow-test.js index f8f94c3..2fa5566 100644 --- a/test/sequence-flow-test.js +++ b/test/sequence-flow-test.js @@ -1,7 +1,8 @@ -import testHelpers from './helpers/testHelpers'; -import types from './helpers/types'; +import factory from './helpers/factory.js'; +import testHelpers from './helpers/testHelpers.js'; +import types from './helpers/types.js'; -import {default as Serializer, TypeResolver, deserialize} from '../index'; +import {default as Serializer, TypeResolver, deserialize} from '../index.js'; const typeResolver = TypeResolver(types); @@ -24,7 +25,7 @@ describe('sequence flow', () => { `; const moddleContext = await testHelpers.moddleContext(source, { - js: require('./resources/js-bpmn-moddle.json'), + js: JSON.parse(factory.resource('js-bpmn-moddle.json')), }); const serializer = Serializer(moddleContext, typeResolver); diff --git a/test/serializer-test.js b/test/serializer-test.js index 11adcc0..667b420 100644 --- a/test/serializer-test.js +++ b/test/serializer-test.js @@ -1,7 +1,8 @@ -import factory from './helpers/factory'; -import testHelpers from './helpers/testHelpers'; -import types from './helpers/types'; -import {default as Serializer, TypeResolver, deserialize, map} from '../index'; +import factory from './helpers/factory.js'; +import fs from 'fs'; +import testHelpers from './helpers/testHelpers.js'; +import types from './helpers/types.js'; +import {default as Serializer, TypeResolver, deserialize, map} from '../index.js'; const lanesSource = factory.resource('lanes.bpmn'); const subProcessSource = factory.resource('sub-process.bpmn'); @@ -25,7 +26,7 @@ describe('moddle context serializer', () => { conditionalFlows; before(async () => { lanesModdleContext = await testHelpers.moddleContext(lanesSource); - lanesModdleContextFromCallBack = require('./resources/lanes-old-callback-context.json'); + lanesModdleContextFromCallBack = JSON.parse(fs.readFileSync('./test/resources/lanes-old-callback-context.json')); subProcessModdleContext = await testHelpers.moddleContext(subProcessSource); eventDefinitionModdleContext = await testHelpers.moddleContext(eventDefinitionSource); conditionAndEscalationModdleContext = await testHelpers.moddleContext(conditionAndEscalationSource); @@ -1863,7 +1864,7 @@ describe('moddle context serializer', () => { `; - const moddleOptions = {camunda: require('camunda-bpmn-moddle/resources/camunda')}; + const moddleOptions = {camunda: testHelpers.getCamundaExtension()}; const context = Serializer(await testHelpers.moddleContext(source, moddleOptions), typeResolver); const task = context.getActivityById('task'); expect(task.behaviour).to.have.property('assignee', 'pal'); diff --git a/test/timer-test.js b/test/timer-test.js index 401a19e..d7a2469 100644 --- a/test/timer-test.js +++ b/test/timer-test.js @@ -1,11 +1,11 @@ -import factory from './helpers/factory'; -import testHelpers from './helpers/testHelpers'; -import types from './helpers/types'; -import camunda from 'camunda-bpmn-moddle/resources/camunda'; +import factory from './helpers/factory.js'; +import testHelpers from './helpers/testHelpers.js'; +import types from './helpers/types.js'; -import {default as Serializer, TypeResolver, deserialize} from '../index'; +import {default as Serializer, TypeResolver, deserialize} from '../index.js'; const typeResolver = TypeResolver(types); +const camunda = testHelpers.getCamundaExtension(); describe('timers', () => { describe('a process with start cycle, bound timeout, and catch date, and user task with extension due date', () => { From a0e626e2ea6d87cb836ff56d2181bbb0fd71b83b Mon Sep 17 00:00:00 2001 From: paed01 Date: Thu, 29 Dec 2022 09:55:18 +0100 Subject: [PATCH 2/2] use github actions over travis can't make travis build node 18 for npm config reasons --- .eslintrc.json | 2 +- .github/workflows/build.yaml | 23 +++++++++++++++++++++++ .travis.yml | 9 --------- CHANGELOG.md | 2 +- README.md | 2 +- babel.config.js | 16 ---------------- test/.eslintrc.json | 13 ++++--------- 7 files changed, 30 insertions(+), 37 deletions(-) create mode 100644 .github/workflows/build.yaml delete mode 100644 .travis.yml delete mode 100644 babel.config.js diff --git a/.eslintrc.json b/.eslintrc.json index 2c7f171..4b415a0 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -2,7 +2,7 @@ "parser": "espree", "parserOptions": { "sourceType": "module", - "ecmaVersion": 2020 + "ecmaVersion": 2018 }, "env": { "es6": true, diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml new file mode 100644 index 0000000..ea1c62c --- /dev/null +++ b/.github/workflows/build.yaml @@ -0,0 +1,23 @@ +name: Build + +on: ["push", "pull_request"] + +jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + node-version: [14.x, 16.x, 18.x, latest] + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v3 + with: + node-version: ${{ matrix.node-version }} + - run: npm i + - run: npm run test:lcov + - name: Coveralls + uses: coverallsapp/github-action@master + with: + github-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 760f136..0000000 --- a/.travis.yml +++ /dev/null @@ -1,9 +0,0 @@ -language: node_js -node_js: -- '14' -- '16' -before_script: - - npm install coveralls -script: npm run test:lcov -after_success: -- cat ./coverage/lcov.info | ./node_modules/.bin/coveralls --verbose diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c8b465..daa8f42 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ Changelog # 3.0.0 -- Converted to module +- Convert to module - Remove backward compatibility test for bpmn-moddle@5 # 2.2.0 diff --git a/README.md b/README.md index 1c4366f..1995162 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ bpmn-moddle context serializer Make bpmn-moddle context serializable and mapped to behaviour functions -[![Build Status](https://app.travis-ci.com/paed01/moddle-context-serializer.svg?branch=master)](https://app.travis-ci.com/paed01/moddle-context-serializer)[![Coverage Status](https://coveralls.io/repos/github/paed01/moddle-context-serializer/badge.svg?branch=master)](https://coveralls.io/github/paed01/moddle-context-serializer?branch=master) +[![build](https://github.com/paed01/moddle-context-serializer/actions/workflows/build.yaml/badge.svg)](https://github.com/paed01/moddle-context-serializer/actions/workflows/build.yaml)[![coverage](https://coveralls.io/repos/github/paed01/moddle-context-serializer/badge.svg?branch=master)](https://coveralls.io/github/paed01/moddle-context-serializer?branch=master) - [API](/API.md) diff --git a/babel.config.js b/babel.config.js deleted file mode 100644 index 4765211..0000000 --- a/babel.config.js +++ /dev/null @@ -1,16 +0,0 @@ -/* global module */ -module.exports = function babelRoot(api) { - api.cache(true); - - return { - presets: [ - [ - '@babel/env', { - targets: { - node: 'current', - }, - }, - ], - ], - }; -}; diff --git a/test/.eslintrc.json b/test/.eslintrc.json index a59557b..074fd35 100644 --- a/test/.eslintrc.json +++ b/test/.eslintrc.json @@ -3,20 +3,15 @@ "node": true, "mocha": true }, + "parserOptions": { + "ecmaVersion": 2020 + }, "rules": { "no-unused-expressions": 0, "no-var": 1, "prefer-arrow-callback": 1 }, "globals": { - "expect": false, - "Buffer": false, - "Feature": false, - "Scenario": false, - "Given": false, - "When": false, - "Then": false, - "And": false, - "But": false + "expect": false } }