function getAugmentedNamespace(n) { var f = n.default; if (typeof f == "function") { var a = function () { return f.apply(this, arguments); }; a.prototype = f.prototype; } else a = {}; Object.defineProperty(a, '__esModule', {value: true}); Object.keys(n).forEach(function (k) { var d = Object.getOwnPropertyDescriptor(n, k); Object.defineProperty(a, k, d.get ? d : { enumerable: true, get: function () { return n[k]; } }); }); return a; } /** * A rule that checks that sequence flows outgoing from a * conditional forking gateway or activity are * either default flows _or_ have a condition attached */ var conditionalFlows = function() { function check(node, reporter) { if (!isConditionalForking(node)) { return; } const outgoing = node.outgoing || []; outgoing.forEach((flow) => { const missingCondition = ( !hasCondition$2(flow) && !isDefaultFlow$1(node, flow) ); if (missingCondition) { reporter.report(flow.id, 'Sequence flow is missing condition', [ 'conditionExpression' ]); } }); } return { check }; }; // helpers ///////////////////////////// function isConditionalForking(node) { const defaultFlow = node['default']; const outgoing = node.outgoing || []; return defaultFlow || outgoing.find(hasCondition$2); } function hasCondition$2(flow) { return !!flow.conditionExpression; } function isDefaultFlow$1(node, flow) { return node['default'] === flow; } /** * Checks whether node is of specific bpmn type. * * @param {ModdleElement} node * @param {String} type * * @return {Boolean} */ function is$g(node, type) { if (type.indexOf(':') === -1) { type = 'bpmn:' + type; } return ( (typeof node.$instanceOf === 'function') ? node.$instanceOf(type) : node.$type === type ); } /** * Checks whether node has any of the specified types. * * @param {ModdleElement} node * @param {Array} types * * @return {Boolean} */ function isAny$6(node, types) { return types.some(function(type) { return is$g(node, type); }); } var index_esm$1 = /*#__PURE__*/Object.freeze({ __proto__: null, is: is$g, isAny: isAny$6 }); var require$$0 = /*@__PURE__*/getAugmentedNamespace(index_esm$1); const { is: is$f, isAny: isAny$5 } = require$$0; /** * A rule that checks the presence of an end event per scope. */ var endEventRequired = function() { function hasEndEvent(node) { const flowElements = node.flowElements || []; return ( flowElements.some(node => is$f(node, 'bpmn:EndEvent')) ); } function check(node, reporter) { if (!isAny$5(node, [ 'bpmn:Process', 'bpmn:SubProcess' ])) { return; } if (!hasEndEvent(node)) { const type = is$f(node, 'bpmn:SubProcess') ? 'Sub process' : 'Process'; reporter.report(node.id, type + ' is missing end event'); } } return { check }; }; const { is: is$e } = require$$0; /** * A rule that checks that start events inside an event sub-process * are typed. */ var eventSubProcessTypedStartEvent = function() { function check(node, reporter) { if (!is$e(node, 'bpmn:SubProcess') || !node.triggeredByEvent) { return; } const flowElements = node.flowElements || []; flowElements.forEach(function(flowElement) { if (!is$e(flowElement, 'bpmn:StartEvent')) { return false; } const eventDefinitions = flowElement.eventDefinitions || []; if (eventDefinitions.length === 0) { reporter.report(flowElement.id, 'Start event is missing event definition', [ 'eventDefinitions' ]); } }); } return { check }; }; const { isAny: isAny$4 } = require$$0; /** * A rule that checks that no fake join is modeled by attempting * to give a task or event join semantics. * * Users should model a parallel joining gateway * to achieve the desired behavior. */ var fakeJoin = function() { function check(node, reporter) { if (!isAny$4(node, [ 'bpmn:Task', 'bpmn:Event' ])) { return; } const incoming = node.incoming || []; if (incoming.length > 1) { reporter.report(node.id, 'Incoming flows do not join'); } } return { check }; }; const { is: is$d, isAny: isAny$3 } = require$$0; /** * A rule that checks the presence of a label. */ var labelRequired = function() { function check(node, reporter) { if (isAny$3(node, [ 'bpmn:ParallelGateway', 'bpmn:EventBasedGateway' ])) { return; } // ignore joining gateways if (is$d(node, 'bpmn:Gateway') && !isForking(node)) { return; } if (is$d(node, 'bpmn:BoundaryEvent')) { return; } // ignore sub-processes if (is$d(node, 'bpmn:SubProcess')) { // TODO(nikku): better ignore expanded sub-processes only return; } // ignore sequence flow without condition if (is$d(node, 'bpmn:SequenceFlow') && !hasCondition$1(node)) { return; } // ignore data objects and artifacts for now if (isAny$3(node, [ 'bpmn:FlowNode', 'bpmn:SequenceFlow', 'bpmn:Participant', 'bpmn:Lane' ])) { const name = (node.name || '').trim(); if (name.length === 0) { reporter.report(node.id, 'Element is missing label/name', [ 'name' ]); } } } return { check }; }; // helpers //////////////////////// function isForking(node) { const outgoing = node.outgoing || []; return outgoing.length > 1; } function hasCondition$1(node) { return node.conditionExpression; } /** * Flatten array, one level deep. * * @param {Array} arr * * @return {Array} */ function flatten$1(arr) { return Array.prototype.concat.apply([], arr); } var nativeToString = Object.prototype.toString; var nativeHasOwnProperty = Object.prototype.hasOwnProperty; function isUndefined(obj) { return obj === undefined; } function isDefined(obj) { return obj !== undefined; } function isNil(obj) { return obj == null; } function isArray(obj) { return nativeToString.call(obj) === '[object Array]'; } function isObject(obj) { return nativeToString.call(obj) === '[object Object]'; } function isNumber(obj) { return nativeToString.call(obj) === '[object Number]'; } function isFunction(obj) { var tag = nativeToString.call(obj); return tag === '[object Function]' || tag === '[object AsyncFunction]' || tag === '[object GeneratorFunction]' || tag === '[object AsyncGeneratorFunction]' || tag === '[object Proxy]'; } function isString(obj) { return nativeToString.call(obj) === '[object String]'; } /** * Ensure collection is an array. * * @param {Object} obj */ function ensureArray(obj) { if (isArray(obj)) { return; } throw new Error('must supply array'); } /** * Return true, if target owns a property with the given key. * * @param {Object} target * @param {String} key * * @return {Boolean} */ function has(target, key) { return nativeHasOwnProperty.call(target, key); } /** * Find element in collection. * * @param {Array|Object} collection * @param {Function|Object} matcher * * @return {Object} */ function find(collection, matcher) { matcher = toMatcher(matcher); var match; forEach(collection, function (val, key) { if (matcher(val, key)) { match = val; return false; } }); return match; } /** * Find element index in collection. * * @param {Array|Object} collection * @param {Function} matcher * * @return {Object} */ function findIndex(collection, matcher) { matcher = toMatcher(matcher); var idx = isArray(collection) ? -1 : undefined; forEach(collection, function (val, key) { if (matcher(val, key)) { idx = key; return false; } }); return idx; } /** * Find element in collection. * * @param {Array|Object} collection * @param {Function} matcher * * @return {Array} result */ function filter(collection, matcher) { var result = []; forEach(collection, function (val, key) { if (matcher(val, key)) { result.push(val); } }); return result; } /** * Iterate over collection; returning something * (non-undefined) will stop iteration. * * @param {Array|Object} collection * @param {Function} iterator * * @return {Object} return result that stopped the iteration */ function forEach(collection, iterator) { var val, result; if (isUndefined(collection)) { return; } var convertKey = isArray(collection) ? toNum : identity; for (var key in collection) { if (has(collection, key)) { val = collection[key]; result = iterator(val, convertKey(key)); if (result === false) { return val; } } } } /** * Return collection without element. * * @param {Array} arr * @param {Function} matcher * * @return {Array} */ function without(arr, matcher) { if (isUndefined(arr)) { return []; } ensureArray(arr); matcher = toMatcher(matcher); return arr.filter(function (el, idx) { return !matcher(el, idx); }); } /** * Reduce collection, returning a single result. * * @param {Object|Array} collection * @param {Function} iterator * @param {Any} result * * @return {Any} result returned from last iterator */ function reduce(collection, iterator, result) { forEach(collection, function (value, idx) { result = iterator(result, value, idx); }); return result; } /** * Return true if every element in the collection * matches the criteria. * * @param {Object|Array} collection * @param {Function} matcher * * @return {Boolean} */ function every(collection, matcher) { return !!reduce(collection, function (matches, val, key) { return matches && matcher(val, key); }, true); } /** * Return true if some elements in the collection * match the criteria. * * @param {Object|Array} collection * @param {Function} matcher * * @return {Boolean} */ function some(collection, matcher) { return !!find(collection, matcher); } /** * Transform a collection into another collection * by piping each member through the given fn. * * @param {Object|Array} collection * @param {Function} fn * * @return {Array} transformed collection */ function map(collection, fn) { var result = []; forEach(collection, function (val, key) { result.push(fn(val, key)); }); return result; } /** * Get the collections keys. * * @param {Object|Array} collection * * @return {Array} */ function keys(collection) { return collection && Object.keys(collection) || []; } /** * Shorthand for `keys(o).length`. * * @param {Object|Array} collection * * @return {Number} */ function size(collection) { return keys(collection).length; } /** * Get the values in the collection. * * @param {Object|Array} collection * * @return {Array} */ function values(collection) { return map(collection, function (val) { return val; }); } /** * Group collection members by attribute. * * @param {Object|Array} collection * @param {Function} extractor * * @return {Object} map with { attrValue => [ a, b, c ] } */ function groupBy(collection, extractor) { var grouped = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; extractor = toExtractor(extractor); forEach(collection, function (val) { var discriminator = extractor(val) || '_'; var group = grouped[discriminator]; if (!group) { group = grouped[discriminator] = []; } group.push(val); }); return grouped; } function uniqueBy(extractor) { extractor = toExtractor(extractor); var grouped = {}; for (var _len = arguments.length, collections = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { collections[_key - 1] = arguments[_key]; } forEach(collections, function (c) { return groupBy(c, extractor, grouped); }); var result = map(grouped, function (val, key) { return val[0]; }); return result; } var unionBy = uniqueBy; /** * Sort collection by criteria. * * @param {Object|Array} collection * @param {String|Function} extractor * * @return {Array} */ function sortBy(collection, extractor) { extractor = toExtractor(extractor); var sorted = []; forEach(collection, function (value, key) { var disc = extractor(value, key); var entry = { d: disc, v: value }; for (var idx = 0; idx < sorted.length; idx++) { var d = sorted[idx].d; if (disc < d) { sorted.splice(idx, 0, entry); return; } } // not inserted, append (!) sorted.push(entry); }); return map(sorted, function (e) { return e.v; }); } /** * Create an object pattern matcher. * * @example * * const matcher = matchPattern({ id: 1 }); * * let element = find(elements, matcher); * * @param {Object} pattern * * @return {Function} matcherFn */ function matchPattern(pattern) { return function (el) { return every(pattern, function (val, key) { return el[key] === val; }); }; } function toExtractor(extractor) { return isFunction(extractor) ? extractor : function (e) { return e[extractor]; }; } function toMatcher(matcher) { return isFunction(matcher) ? matcher : function (e) { return e === matcher; }; } function identity(arg) { return arg; } function toNum(arg) { return Number(arg); } /** * Debounce fn, calling it only once if the given time * elapsed between calls. * * Lodash-style the function exposes methods to `#clear` * and `#flush` to control internal behavior. * * @param {Function} fn * @param {Number} timeout * * @return {Function} debounced function */ function debounce(fn, timeout) { var timer; var lastArgs; var lastThis; var lastNow; function fire(force) { var now = Date.now(); var scheduledDiff = force ? 0 : lastNow + timeout - now; if (scheduledDiff > 0) { return schedule(scheduledDiff); } fn.apply(lastThis, lastArgs); clear(); } function schedule(timeout) { timer = setTimeout(fire, timeout); } function clear() { if (timer) { clearTimeout(timer); } timer = lastNow = lastArgs = lastThis = undefined; } function flush() { if (timer) { fire(true); } clear(); } function callback() { lastNow = Date.now(); for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } lastArgs = args; lastThis = this; // ensure an execution is scheduled if (!timer) { schedule(timeout); } } callback.flush = flush; callback.cancel = clear; return callback; } /** * Throttle fn, calling at most once * in the given interval. * * @param {Function} fn * @param {Number} interval * * @return {Function} throttled function */ function throttle(fn, interval) { var throttling = false; return function () { if (throttling) { return; } fn.apply(void 0, arguments); throttling = true; setTimeout(function () { throttling = false; }, interval); }; } /** * Bind function against target . * * @param {Function} fn * @param {Object} target * * @return {Function} bound function */ function bind(fn, target) { return fn.bind(target); } function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function (obj) { return typeof obj; }; } else { _typeof = function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } /** * Convenience wrapper for `Object.assign`. * * @param {Object} target * @param {...Object} others * * @return {Object} the target */ function assign(target) { for (var _len = arguments.length, others = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { others[_key - 1] = arguments[_key]; } return _extends.apply(void 0, [target].concat(others)); } /** * Sets a nested property of a given object to the specified value. * * This mutates the object and returns it. * * @param {Object} target The target of the set operation. * @param {(string|number)[]} path The path to the nested value. * @param {any} value The value to set. */ function set(target, path, value) { var currentTarget = target; forEach(path, function (key, idx) { if (typeof key !== 'number' && typeof key !== 'string') { throw new Error('illegal key type: ' + _typeof(key) + '. Key should be of type number or string.'); } if (key === 'constructor') { throw new Error('illegal key: constructor'); } if (key === '__proto__') { throw new Error('illegal key: __proto__'); } var nextKey = path[idx + 1]; var nextTarget = currentTarget[key]; if (isDefined(nextKey) && isNil(nextTarget)) { nextTarget = currentTarget[key] = isNaN(+nextKey) ? {} : []; } if (isUndefined(nextKey)) { if (isUndefined(value)) { delete currentTarget[key]; } else { currentTarget[key] = value; } } else { currentTarget = nextTarget; } }); return target; } /** * Gets a nested property of a given object. * * @param {Object} target The target of the get operation. * @param {(string|number)[]} path The path to the nested value. * @param {any} [defaultValue] The value to return if no value exists. */ function get(target, path, defaultValue) { var currentTarget = target; forEach(path, function (key) { // accessing nil property yields if (isNil(currentTarget)) { currentTarget = undefined; return false; } currentTarget = currentTarget[key]; }); return isUndefined(currentTarget) ? defaultValue : currentTarget; } /** * Pick given properties from the target object. * * @param {Object} target * @param {Array} properties * * @return {Object} target */ function pick(target, properties) { var result = {}; var obj = Object(target); forEach(properties, function (prop) { if (prop in obj) { result[prop] = target[prop]; } }); return result; } /** * Pick all target properties, excluding the given ones. * * @param {Object} target * @param {Array} properties * * @return {Object} target */ function omit(target, properties) { var result = {}; var obj = Object(target); forEach(obj, function (prop, key) { if (properties.indexOf(key) === -1) { result[key] = prop; } }); return result; } /** * Recursively merge `...sources` into given target. * * Does support merging objects; does not support merging arrays. * * @param {Object} target * @param {...Object} sources * * @return {Object} the target */ function merge(target) { for (var _len2 = arguments.length, sources = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) { sources[_key2 - 1] = arguments[_key2]; } if (!sources.length) { return target; } forEach(sources, function (source) { // skip non-obj sources, i.e. null if (!source || !isObject(source)) { return; } forEach(source, function (sourceVal, key) { if (key === '__proto__') { return; } var targetVal = target[key]; if (isObject(sourceVal)) { if (!isObject(targetVal)) { // override target[key] with object targetVal = {}; } target[key] = merge(targetVal, sourceVal); } else { target[key] = sourceVal; } }); }); return target; } var index_esm = /*#__PURE__*/Object.freeze({ __proto__: null, assign: assign, bind: bind, debounce: debounce, ensureArray: ensureArray, every: every, filter: filter, find: find, findIndex: findIndex, flatten: flatten$1, forEach: forEach, get: get, groupBy: groupBy, has: has, isArray: isArray, isDefined: isDefined, isFunction: isFunction, isNil: isNil, isNumber: isNumber, isObject: isObject, isString: isString, isUndefined: isUndefined, keys: keys, map: map, matchPattern: matchPattern, merge: merge, omit: omit, pick: pick, reduce: reduce, set: set, size: size, some: some, sortBy: sortBy, throttle: throttle, unionBy: unionBy, uniqueBy: uniqueBy, values: values, without: without }); var require$$1 = /*@__PURE__*/getAugmentedNamespace(index_esm); const { is: is$c } = require$$0; const { flatten } = require$$1; /** * A rule that checks that there is no BPMNDI information missing for elements, * which require BPMNDI. */ var noBpmndi = function() { function check(node, reporter) { if (!is$c(node, 'bpmn:Definitions')) { return false; } // (1) Construct array of all BPMN elements const bpmnElements = getAllBpmnElements(node.rootElements); // (2) Filter BPMN elements without visual representation const visualBpmnElements = bpmnElements.filter(hasVisualRepresentation); // (3) Construct array of BPMNDI references const diBpmnReferences = getAllDiBpmnReferences(node); // (4) Report elements without BPMNDI visualBpmnElements.forEach((element) => { if (diBpmnReferences.indexOf(element.id) === -1) { reporter.report(element.id, 'Element is missing bpmndi'); } }); } return { check }; }; // helpers ///////////////////////////// /** * Get all BPMN elements within a bpmn:Definitions node * * @param {array} rootElements - An array of Moddle rootElements * @return {array} A flat array with all BPMN elements, each represented with { id: elementId, $type: elementType } * */ function getAllBpmnElements(rootElements) { return flatten(rootElements.map((rootElement) => { const laneSet = rootElement.laneSets && rootElement.laneSets[0] || rootElement.childLaneSet; // Include // * flowElements (e.g., tasks, sequenceFlows), // * nested flowElements, // * participants, // * artifacts (groups), // * laneSets // * nested laneSets // * childLaneSets // * nested childLaneSets // * messageFlows const elements = flatten([].concat( rootElement.flowElements || [], (rootElement.flowElements && getAllBpmnElements(rootElement.flowElements.filter(hasFlowElements))) || [], rootElement.participants || [], rootElement.artifacts || [], laneSet && laneSet.lanes || [], laneSet && laneSet.lanes && getAllBpmnElements(laneSet.lanes.filter(hasChildLaneSet)) || [], rootElement.messageFlows || [] )); if (elements.length > 0) { return elements.map((element) => { return { id: element.id, $type: element.$type }; }); } else { // We are not interested in the rest here (DI) return []; } })); } /** * Get all BPMN elements within a bpmn:Definitions node * * @param {ModdleElement} definitionsNode - A moddleElement representing the * bpmn:Definitions element * @return {array} A flat array with all BPMNDI element ids part of * this bpmn:Definitions node * */ function getAllDiBpmnReferences(definitionsNode) { return flatten( definitionsNode.diagrams.map((diagram) => { const diElements = diagram.plane.planeElement || []; return diElements.map((element) => { return element.bpmnElement.id; }); }) ); } function hasVisualRepresentation(element) { const noVisRepresentation = [ 'bpmn:DataObject' ]; return noVisRepresentation.includes(element.$type) ? false : true; } function hasFlowElements(element) { return element.flowElements ? true : false; } function hasChildLaneSet(element) { return element.childLaneSet ? true : false; } var helper = {}; const { is: is$b } = require$$0; /** * Create a checker that disallows the given element type. * * @param {String} type * * @return {Function} ruleImpl */ function disallowNodeType$2(type) { return function() { function check(node, reporter) { if (is$b(node, type)) { reporter.report(node.id, 'Element has disallowed type <' + type + '>'); } } return { check }; }; } helper.disallowNodeType = disallowNodeType$2; const disallowNodeType$1 = helper.disallowNodeType; var noComplexGateway = disallowNodeType$1('bpmn:ComplexGateway'); const { isAny: isAny$2, is: is$a } = require$$0; /** * A rule that verifies that there exists no disconnected * flow elements, i.e. elements without incoming * _or_ outgoing sequence flows */ var noDisconnected = function() { function check(node, reporter) { if (!isAny$2(node, [ 'bpmn:Task', 'bpmn:Gateway', 'bpmn:SubProcess', 'bpmn:Event' ]) || node.triggeredByEvent) { return; } // compensation activity and boundary events are // linked visually via associations. If these associations // exist we are fine, too if (isCompensationLinked(node)) { return; } const incoming = node.incoming || []; const outgoing = node.outgoing || []; if (!incoming.length && !outgoing.length) { reporter.report(node.id, 'Element is not connected'); } } return { check }; }; // helpers ///////////////// function isCompensationBoundary(node) { var eventDefinitions = node.eventDefinitions; if (!is$a(node, 'bpmn:BoundaryEvent')) { return false; } if (!eventDefinitions || eventDefinitions.length !== 1) { return false; } return is$a(eventDefinitions[0], 'bpmn:CompensateEventDefinition'); } function isCompensationActivity(node) { return node.isForCompensation; } function isCompensationLinked(node) { var source = isCompensationBoundary(node); var target = isCompensationActivity(node); // TODO(nikku): check, whether compensation association exists return source || target; } const { is: is$9 } = require$$0; /** * A rule that verifies that there are no disconnected * flow elements, i.e. elements without incoming * _or_ outgoing sequence flows */ var noDuplicateSequenceFlows = function() { const keyed = {}; const outgoingReported = {}; const incomingReported = {}; function check(node, reporter) { if (!is$9(node, 'bpmn:SequenceFlow')) { return; } const key = flowKey(node); if (key in keyed) { reporter.report(node.id, 'SequenceFlow is a duplicate'); const sourceId = node.sourceRef.id; const targetId = node.targetRef.id; if (!outgoingReported[sourceId]) { reporter.report(sourceId, 'Duplicate outgoing sequence flows'); outgoingReported[sourceId] = true; } if (!incomingReported[targetId]) { reporter.report(targetId, 'Duplicate incoming sequence flows'); incomingReported[targetId] = true; } } else { keyed[key] = node; } } return { check }; }; // helpers ///////////////// function flowKey(flow) { const conditionExpression = flow.conditionExpression; const condition = conditionExpression ? conditionExpression.body : ''; const source = flow.sourceRef ? flow.sourceRef.id : flow.id; const target = flow.targetRef ? flow.targetRef.id : flow.id; return source + '#' + target + '#' + condition; } const { is: is$8 } = require$$0; /** * A rule that checks, whether a gateway forks and joins * at the same time. */ var noGatewayJoinFork = function() { function check(node, reporter) { if (!is$8(node, 'bpmn:Gateway')) { return; } const incoming = node.incoming || []; const outgoing = node.outgoing || []; if (incoming.length > 1 && outgoing.length > 1) { reporter.report(node.id, 'Gateway forks and joins'); } } return { check }; }; const { isAny: isAny$1 } = require$$0; /** * A rule that checks that no implicit split is modeled * starting from a task. * * users should model the parallel splitting gateway * explicitly instead. */ var noImplicitSplit = function() { function check(node, reporter) { if (!isAny$1(node, [ 'bpmn:Task', 'bpmn:Event' ])) { return; } const outgoing = node.outgoing || []; const outgoingWithoutCondition = outgoing.filter((flow) => { return !hasCondition(flow) && !isDefaultFlow(node, flow); }); if (outgoingWithoutCondition.length > 1) { reporter.report(node.id, 'Flow splits implicitly'); } } return { check }; }; // helpers ///////////////////////////// function hasCondition(flow) { return !!flow.conditionExpression; } function isDefaultFlow(node, flow) { return node['default'] === flow; } const disallowNodeType = helper.disallowNodeType; var noInclusiveGateway = disallowNodeType('bpmn:InclusiveGateway'); const { is: is$7 } = require$$0; /** * A rule that checks whether not more than one blank start event * exists per scope. */ var singleBlankStartEvent = function() { function check(node, reporter) { if (!is$7(node, 'bpmn:FlowElementsContainer')) { return; } const flowElements = node.flowElements || []; const blankStartEvents = flowElements.filter(function(flowElement) { if (!is$7(flowElement, 'bpmn:StartEvent')) { return false; } const eventDefinitions = flowElement.eventDefinitions || []; return eventDefinitions.length === 0; }); if (blankStartEvents.length > 1) { const type = is$7(node, 'bpmn:SubProcess') ? 'Sub process' : 'Process'; reporter.report(node.id, type + ' has multiple blank start events'); } } return { check }; }; const { is: is$6 } = require$$0; /** * A rule that verifies that an event contains maximum one event definition. */ var singleEventDefinition = function() { function check(node, reporter) { if (!is$6(node, 'bpmn:Event')) { return; } const eventDefinitions = node.eventDefinitions || []; if (eventDefinitions.length > 1) { reporter.report(node.id, 'Event has multiple event definitions', [ 'eventDefinitions' ]); } } return { check }; }; const { is: is$5, isAny } = require$$0; /** * A rule that checks for the presence of a start event per scope. */ var startEventRequired = function() { function hasStartEvent(node) { const flowElements = node.flowElements || []; return ( flowElements.some(node => is$5(node, 'bpmn:StartEvent')) ); } function check(node, reporter) { if (!isAny(node, [ 'bpmn:Process', 'bpmn:SubProcess' ])) { return; } if (!hasStartEvent(node)) { const type = is$5(node, 'bpmn:SubProcess') ? 'Sub process' : 'Process'; reporter.report(node.id, type + ' is missing start event'); } } return { check }; }; const { is: is$4 } = require$$0; /** * A rule that checks that start events inside a normal sub-processes * are blank (do not have an event definition). */ var subProcessBlankStartEvent = function() { function check(node, reporter) { if (!is$4(node, 'bpmn:SubProcess') || node.triggeredByEvent) { return; } const flowElements = node.flowElements || []; flowElements.forEach(function(flowElement) { if (!is$4(flowElement, 'bpmn:StartEvent')) { return false; } const eventDefinitions = flowElement.eventDefinitions || []; if (eventDefinitions.length > 0) { reporter.report(flowElement.id, 'Start event must be blank', [ 'eventDefinitions' ]); } }); } return { check }; }; const { is: is$3 } = require$$0; /** * A rule that checks, whether a gateway has only one source and target. * * Those gateways are superfluous since they don't do anything. */ var superfluousGateway = function() { function check(node, reporter) { if (!is$3(node, 'bpmn:Gateway')) { return; } const incoming = node.incoming || []; const outgoing = node.outgoing || []; if (incoming.length === 1 && outgoing.length === 1) { reporter.report(node.id, 'Gateway is superfluous. It only has one source and target.'); } } return { check }; }; const { is: is$2 } = require$$0; /** * Rule that reports missing targetNamespace on bpmn:Definitions. */ var targetNamespace = function() { function check(node, reporter) { if (is$2(node, 'bpmn:Definitions') && !node.targetNamespace) { reporter.report(node.id, 'Element is missing targetNamespace'); } } return { check: check }; }; const { is: is$1 } = require$$0; /** * Rule that reports manual tasks being used. */ var noManualTask = function() { function check(node, reporter) { if (is$1(node, 'bpmn:ManualTask')) { reporter.report(node.id, 'Element has disallowed type bpmn:ManualTask'); } } return { check: check }; }; const { is } = require$$0; /** * 校验任务节点是否设置任务处理人 */ var checkNodeUser = function () { function check(node, reporter) { if (is(node, 'bpmn:Task')) { const assignee = (node.assignee || '').trim(); const candidateUsers = (node.candidateUsers || '').trim(); const candidateGroups = (node.candidateGroups || '').trim(); if (assignee.length === 0 && candidateUsers.length === 0 && candidateGroups.length === 0) { reporter.report(node.id, '任务节点未设置人员信息'); } const buttons = node.extensionElements?.values?.filter(ex => { return ex.$type === `flowable:Buttons`; }) ?? []; const selectButtons = buttons.reduce((pre, current) => pre.concat(current.values), []); if (buttons.length === 0 || selectButtons.length === 0) { reporter.report(node.id, '任务节点未配置按钮信息'); } } } return { check: check }; }; const cache = {}; /** * A resolver that caches rules and configuration as part of the bundle, * making them accessible in the browser. * * @param {Object} cache */ function Resolver() {} Resolver.prototype.resolveRule = function(pkg, ruleName) { const rule = cache[pkg + '/' + ruleName]; if (!rule) { throw new Error('cannot resolve rule <' + pkg + '/' + ruleName + '>'); } return rule; }; Resolver.prototype.resolveConfig = function(pkg, configName) { throw new Error( 'cannot resolve config <' + configName + '> in <' + pkg +'>' ); }; const resolver = new Resolver(); const rules = { "conditional-flows": "error", "end-event-required": "error", "event-sub-process-typed-start-event": "error", "fake-join": "warn", "label-required": "warn", "no-bpmndi": "error", "no-complex-gateway": "error", "no-disconnected": "error", "no-duplicate-sequence-flows": "error", "no-gateway-join-fork": "error", "no-implicit-split": "error", "no-inclusive-gateway": "error", "single-blank-start-event": "error", "single-event-definition": "error", "start-event-required": "error", "sub-process-blank-start-event": "error", "superfluous-gateway": "warn", "custom/target-namespace": "error", "custom/no-manual-task": "warn", "custom/check-node-user": "error" }; const config = { rules: rules }; const bundle = { resolver: resolver, config: config }; cache['bpmnlint/conditional-flows'] = conditionalFlows; cache['bpmnlint/end-event-required'] = endEventRequired; cache['bpmnlint/event-sub-process-typed-start-event'] = eventSubProcessTypedStartEvent; cache['bpmnlint/fake-join'] = fakeJoin; cache['bpmnlint/label-required'] = labelRequired; cache['bpmnlint/no-bpmndi'] = noBpmndi; cache['bpmnlint/no-complex-gateway'] = noComplexGateway; cache['bpmnlint/no-disconnected'] = noDisconnected; cache['bpmnlint/no-duplicate-sequence-flows'] = noDuplicateSequenceFlows; cache['bpmnlint/no-gateway-join-fork'] = noGatewayJoinFork; cache['bpmnlint/no-implicit-split'] = noImplicitSplit; cache['bpmnlint/no-inclusive-gateway'] = noInclusiveGateway; cache['bpmnlint/single-blank-start-event'] = singleBlankStartEvent; cache['bpmnlint/single-event-definition'] = singleEventDefinition; cache['bpmnlint/start-event-required'] = startEventRequired; cache['bpmnlint/sub-process-blank-start-event'] = subProcessBlankStartEvent; cache['bpmnlint/superfluous-gateway'] = superfluousGateway; cache['bpmnlint-plugin-custom/target-namespace'] = targetNamespace; cache['bpmnlint-plugin-custom/no-manual-task'] = noManualTask; cache['bpmnlint-plugin-custom/check-node-user'] = checkNodeUser; export { config, bundle as default, resolver };