bpmn-js-element-templates
Version:
Element templates for bpmn-js
1,859 lines (1,745 loc) • 2.71 MB
JavaScript
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.BpmnJSElementTemplates = {}));
})(this, (function (exports) { 'use strict';
/**
* @typedef { {
* [key: string]: string;
* } } TranslateReplacements
*/
/**
* A simple translation stub to be used for multi-language support
* in diagrams. Can be easily replaced with a more sophisticated
* solution.
*
* @example
*
* ```javascript
* // use it inside any diagram component by injecting `translate`.
*
* function MyService(translate) {
* alert(translate('HELLO {you}', { you: 'You!' }));
* }
* ```
*
* @param {string} template to interpolate
* @param {TranslateReplacements} [replacements] a map with substitutes
*
* @return {string} the translated string
*/
function translate(template, replacements) {
replacements = replacements || {};
return template.replace(/{([^}]+)}/g, function (_, key) {
return replacements[key] || '{' + key + '}';
});
}
/**
* @type { import('didi').ModuleDeclaration }
*/
var translateModule = {
translate: ['value', translate]
};
/**
* Flatten array, one level deep.
*
* @template T
*
* @param {T[][]} arr
*
* @return {T[]}
*/
function flatten$1(arr) {
return Array.prototype.concat.apply([], arr);
}
const nativeToString = Object.prototype.toString;
const nativeHasOwnProperty = Object.prototype.hasOwnProperty;
function isUndefined$1(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]';
}
/**
* @param {any} obj
*
* @return {boolean}
*/
function isFunction(obj) {
const 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);
}
/**
* @template T
* @typedef { (
* ((e: T) => boolean) |
* ((e: T, idx: number) => boolean) |
* ((e: T, key: string) => boolean) |
* string |
* number
* ) } Matcher
*/
/**
* @template T
* @template U
*
* @typedef { (
* ((e: T) => U) | string | number
* ) } Extractor
*/
/**
* @template T
* @typedef { (val: T, key: any) => boolean } MatchFn
*/
/**
* @template T
* @typedef { T[] } ArrayCollection
*/
/**
* @template T
* @typedef { { [key: string]: T } } StringKeyValueCollection
*/
/**
* @template T
* @typedef { { [key: number]: T } } NumberKeyValueCollection
*/
/**
* @template T
* @typedef { StringKeyValueCollection<T> | NumberKeyValueCollection<T> } KeyValueCollection
*/
/**
* @template T
* @typedef { KeyValueCollection<T> | ArrayCollection<T> } Collection
*/
/**
* Find element in collection.
*
* @template T
* @param {Collection<T>} collection
* @param {Matcher<T>} matcher
*
* @return {Object}
*/
function find$1(collection, matcher) {
const matchFn = toMatcher(matcher);
let match;
forEach(collection, function (val, key) {
if (matchFn(val, key)) {
match = val;
return false;
}
});
return match;
}
/**
* Find element index in collection.
*
* @template T
* @param {Collection<T>} collection
* @param {Matcher<T>} matcher
*
* @return {number}
*/
function findIndex$1(collection, matcher) {
const matchFn = toMatcher(matcher);
let idx = isArray(collection) ? -1 : undefined;
forEach(collection, function (val, key) {
if (matchFn(val, key)) {
idx = key;
return false;
}
});
return idx;
}
/**
* Filter elements in collection.
*
* @template T
* @param {Collection<T>} collection
* @param {Matcher<T>} matcher
*
* @return {T[]} result
*/
function filter(collection, matcher) {
const matchFn = toMatcher(matcher);
let result = [];
forEach(collection, function (val, key) {
if (matchFn(val, key)) {
result.push(val);
}
});
return result;
}
/**
* Iterate over collection; returning something
* (non-undefined) will stop iteration.
*
* @template T
* @param {Collection<T>} collection
* @param { ((item: T, idx: number) => (boolean|void)) | ((item: T, key: string) => (boolean|void)) } iterator
*
* @return {T} return result that stopped the iteration
*/
function forEach(collection, iterator) {
let val, result;
if (isUndefined$1(collection)) {
return;
}
const convertKey = isArray(collection) ? toNum : identity;
for (let key in collection) {
if (has(collection, key)) {
val = collection[key];
result = iterator(val, convertKey(key));
if (result === false) {
return val;
}
}
}
}
/**
* Return collection without element.
*
* @template T
* @param {ArrayCollection<T>} arr
* @param {Matcher<T>} matcher
*
* @return {T[]}
*/
function without(arr, matcher) {
if (isUndefined$1(arr)) {
return [];
}
ensureArray(arr);
const matchFn = toMatcher(matcher);
return arr.filter(function (el, idx) {
return !matchFn(el, idx);
});
}
/**
* Reduce collection, returning a single result.
*
* @template T
* @template V
*
* @param {Collection<T>} collection
* @param {(result: V, entry: T, index: any) => V} iterator
* @param {V} result
*
* @return {V} 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$1(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$1(collection, fn) {
let 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$1(collection, val => val);
}
/**
* Group collection members by attribute.
*
* @param {Object|Array} collection
* @param {Extractor} extractor
*
* @return {Object} map with { attrValue => [ a, b, c ] }
*/
function groupBy(collection, extractor, grouped = {}) {
extractor = toExtractor(extractor);
forEach(collection, function (val) {
let discriminator = extractor(val) || '_';
let group = grouped[discriminator];
if (!group) {
group = grouped[discriminator] = [];
}
group.push(val);
});
return grouped;
}
function uniqueBy(extractor, ...collections) {
extractor = toExtractor(extractor);
let grouped = {};
forEach(collections, c => groupBy(c, extractor, grouped));
let result = map$1(grouped, function (val, key) {
return val[0];
});
return result;
}
const unionBy = uniqueBy;
/**
* Sort collection by criteria.
*
* @template T
*
* @param {Collection<T>} collection
* @param {Extractor<T, number | string>} extractor
*
* @return {Array}
*/
function sortBy(collection, extractor) {
extractor = toExtractor(extractor);
let sorted = [];
forEach(collection, function (value, key) {
let disc = extractor(value, key);
let entry = {
d: disc,
v: value
};
for (var idx = 0; idx < sorted.length; idx++) {
let {
d
} = sorted[idx];
if (disc < d) {
sorted.splice(idx, 0, entry);
return;
}
}
// not inserted, append (!)
sorted.push(entry);
});
return map$1(sorted, e => e.v);
}
/**
* Create an object pattern matcher.
*
* @example
*
* ```javascript
* const matcher = matchPattern({ id: 1 });
*
* let element = find(elements, matcher);
* ```
*
* @template T
*
* @param {T} pattern
*
* @return { (el: any) => boolean } matcherFn
*/
function matchPattern(pattern) {
return function (el) {
return every(pattern, function (val, key) {
return el[key] === val;
});
};
}
/**
* @param {string | ((e: any) => any) } extractor
*
* @return { (e: any) => any }
*/
function toExtractor(extractor) {
/**
* @satisfies { (e: any) => any }
*/
return isFunction(extractor) ? extractor : e => {
// @ts-ignore: just works
return e[extractor];
};
}
/**
* @template T
* @param {Matcher<T>} matcher
*
* @return {MatchFn<T>}
*/
function toMatcher(matcher) {
return isFunction(matcher) ? matcher : e => {
return e === matcher;
};
}
function identity(arg) {
return arg;
}
function toNum(arg) {
return Number(arg);
}
/* global setTimeout clearTimeout */
/**
* @typedef { {
* (...args: any[]): any;
* flush: () => void;
* cancel: () => void;
* } } DebouncedFunction
*/
/**
* 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 {DebouncedFunction} debounced function
*/
function debounce(fn, timeout) {
let timer;
let lastArgs;
let lastThis;
let lastNow;
function fire(force) {
let now = Date.now();
let 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();
}
/**
* @type { DebouncedFunction }
*/
function callback(...args) {
lastNow = Date.now();
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) {
let throttling = false;
return function (...args) {
if (throttling) {
return;
}
fn(...args);
throttling = true;
setTimeout(() => {
throttling = false;
}, interval);
};
}
/**
* Bind function against target <this>.
*
* @param {Function} fn
* @param {Object} target
*
* @return {Function} bound function
*/
function bind(fn, target) {
return fn.bind(target);
}
/**
* Convenience wrapper for `Object.assign`.
*
* @param {Object} target
* @param {...Object} others
*
* @return {Object} the target
*/
function assign(target, ...others) {
return Object.assign(target, ...others);
}
/**
* Sets a nested property of a given object to the specified value.
*
* This mutates the object and returns it.
*
* @template T
*
* @param {T} target The target of the set operation.
* @param {(string|number)[]} path The path to the nested value.
* @param {any} value The value to set.
*
* @return {T}
*/
function set(target, path, value) {
let 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__');
}
let nextKey = path[idx + 1];
let nextTarget = currentTarget[key];
if (isDefined(nextKey) && isNil(nextTarget)) {
nextTarget = currentTarget[key] = isNaN(+nextKey) ? {} : [];
}
if (isUndefined$1(nextKey)) {
if (isUndefined$1(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.
*
* @return {any}
*/
function get(target, path, defaultValue) {
let currentTarget = target;
forEach(path, function (key) {
// accessing nil property yields <undefined>
if (isNil(currentTarget)) {
currentTarget = undefined;
return false;
}
currentTarget = currentTarget[key];
});
return isUndefined$1(currentTarget) ? defaultValue : currentTarget;
}
/**
* Pick properties from the given target.
*
* @template T
* @template {any[]} V
*
* @param {T} target
* @param {V} properties
*
* @return Pick<T, V>
*/
function pick(target, properties) {
let result = {};
let 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.
*
* @template T
* @template {any[]} V
*
* @param {T} target
* @param {V} properties
*
* @return {Omit<T, V>} target
*/
function omit(target, properties) {
let result = {};
let 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, ...sources) {
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;
}
let 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$1,
findIndex: findIndex$1,
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$1,
keys: keys,
map: map$1,
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
});
/**
* @typedef { import('../model/Types').Element } Element
* @typedef { import('../model/Types').ModdleElement } ModdleElement
*/
/**
* Is an element of the given BPMN type?
*
* @param {Element|ModdleElement} element
* @param {string} type
*
* @return {boolean}
*/
function is$4(element, type) {
var bo = getBusinessObject$1(element);
return bo && typeof bo.$instanceOf === 'function' && bo.$instanceOf(type);
}
/**
* Return true if element has any of the given types.
*
* @param {Element|ModdleElement} element
* @param {string[]} types
*
* @return {boolean}
*/
function isAny(element, types) {
return some(types, function (t) {
return is$4(element, t);
});
}
/**
* Return the business object for a given element.
*
* @param {Element|ModdleElement} element
*
* @return {ModdleElement}
*/
function getBusinessObject$1(element) {
return element && element.businessObject || element;
}
/**
* Return the di object for a given element.
*
* @param {Element} element
*
* @return {ModdleElement}
*/
function getDi(element) {
return element && element.di;
}
/**
* @param {Element} element
*
* @return {boolean}
*/
function isEventSubProcess(element) {
return element && !!getBusinessObject$1(element).triggeredByEvent;
}
const PROPERTY_TYPE$1 = 'property';
const ZEBBE_PROPERTY_TYPE = 'zeebe:property';
const ZEBBE_INPUT_TYPE = 'zeebe:input';
const ZEEBE_OUTPUT_TYPE = 'zeebe:output';
const ZEEBE_PROPERTY_TYPE = 'zeebe:property';
const ZEEBE_TASK_DEFINITION_TYPE_TYPE = 'zeebe:taskDefinition:type';
const ZEEBE_TASK_DEFINITION = 'zeebe:taskDefinition';
const ZEEBE_TASK_HEADER_TYPE = 'zeebe:taskHeader';
const MESSAGE_PROPERTY_TYPE = 'bpmn:Message#property';
const MESSAGE_ZEEBE_SUBSCRIPTION_PROPERTY_TYPE = 'bpmn:Message#zeebe:subscription#property';
const ZEEBE_CALLED_ELEMENT = 'zeebe:calledElement';
const EXTENSION_BINDING_TYPES$1 = [MESSAGE_ZEEBE_SUBSCRIPTION_PROPERTY_TYPE, ZEBBE_INPUT_TYPE, ZEEBE_OUTPUT_TYPE, ZEEBE_PROPERTY_TYPE, ZEEBE_TASK_DEFINITION_TYPE_TYPE, ZEEBE_TASK_DEFINITION, ZEEBE_TASK_HEADER_TYPE, ZEEBE_CALLED_ELEMENT];
const TASK_DEFINITION_TYPES = [ZEEBE_TASK_DEFINITION_TYPE_TYPE, ZEEBE_TASK_DEFINITION];
const IO_BINDING_TYPES$1 = [ZEBBE_INPUT_TYPE, ZEEBE_OUTPUT_TYPE];
const MESSAGE_BINDING_TYPES = [MESSAGE_PROPERTY_TYPE, MESSAGE_ZEEBE_SUBSCRIPTION_PROPERTY_TYPE];
const PROPERTY_BINDING_TYPES = [PROPERTY_TYPE$1, MESSAGE_PROPERTY_TYPE];
function getTaskDefinitionPropertyName(binding) {
return binding.type === ZEEBE_TASK_DEFINITION_TYPE_TYPE ? 'type' : binding.property;
}
// Unique ID creation requires a high quality random # generator. In the browser we therefore
// require the crypto API and do not support built-in fallback to lower quality random number
// generators (like Math.random()).
let getRandomValues;
const rnds8 = new Uint8Array(16);
function rng() {
// lazy load so that environments that need to polyfill have a chance to do so
if (!getRandomValues) {
// getRandomValues needs to be invoked in a context where "this" is a Crypto implementation.
getRandomValues = typeof crypto !== 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto);
if (!getRandomValues) {
throw new Error('crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported');
}
}
return getRandomValues(rnds8);
}
/**
* Convert array of 16 byte values to UUID string format of the form:
* XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
*/
const byteToHex = [];
for (let i = 0; i < 256; ++i) {
byteToHex.push((i + 0x100).toString(16).slice(1));
}
function unsafeStringify(arr, offset = 0) {
// Note: Be careful editing this code! It's been tuned for performance
// and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434
return byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + '-' + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + '-' + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + '-' + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + '-' + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]];
}
const randomUUID = typeof crypto !== 'undefined' && crypto.randomUUID && crypto.randomUUID.bind(crypto);
var native = {
randomUUID
};
function v4(options, buf, offset) {
if (native.randomUUID && !buf && !options) {
return native.randomUUID();
}
options = options || {};
const rnds = options.random || (options.rng || rng)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`
rnds[6] = rnds[6] & 0x0f | 0x40;
rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided
if (buf) {
offset = offset || 0;
for (let i = 0; i < 16; ++i) {
buf[offset + i] = rnds[i];
}
return buf;
}
return unsafeStringify(rnds);
}
/**
* The BPMN 2.0 extension attribute name under
* which the element template ID is stored.
*
* @type {String}
*/
const TEMPLATE_ID_ATTR$1 = 'zeebe:modelerTemplate';
/**
* The BPMN 2.0 extension attribute name under
* which the element template version is stored.
*
* @type {String}
*/
const TEMPLATE_VERSION_ATTR$1 = 'zeebe:modelerTemplateVersion';
/**
* Get template id for a given diagram element.
*
* @param {djs.model.Base} element
*
* @return {String}
*/
function getTemplateId$1(element) {
const businessObject = getBusinessObject$1(element);
if (businessObject) {
return businessObject.get(TEMPLATE_ID_ATTR$1);
}
}
/**
* Get template version for a given diagram element.
*
* @param {djs.model.Base} element
*
* @return {String}
*/
function getTemplateVersion$1(element) {
const businessObject = getBusinessObject$1(element);
if (businessObject) {
return businessObject.get(TEMPLATE_VERSION_ATTR$1);
}
}
/**
* Find extension with given type in
* BPMN element, diagram element or ExtensionElement.
*
* @param {ModdleElement|djs.model.Base} element
* @param {String} type
*
* @return {ModdleElement} the extension
*/
function findExtension$1(element, type) {
const businessObject = getBusinessObject$1(element);
let extensionElements;
if (is$4(businessObject, 'bpmn:ExtensionElements')) {
extensionElements = businessObject;
} else {
extensionElements = businessObject.get('extensionElements');
}
if (!extensionElements) {
return;
}
return extensionElements.get('values').find(value => {
return is$4(value, type);
});
}
function findZeebeProperty(zeebeProperties, binding) {
return zeebeProperties.get('properties').find(value => {
return value.name === binding.name;
});
}
function findInputParameter$1(ioMapping, binding) {
const parameters = ioMapping.get('inputParameters');
return parameters.find(parameter => {
return parameter.target === binding.name;
});
}
function findOutputParameter$1(ioMapping, binding) {
const parameters = ioMapping.get('outputParameters');
return parameters.find(parameter => {
return parameter.source === binding.source;
});
}
function findTaskHeader(taskHeaders, binding) {
const headers = taskHeaders.get('values');
return headers.find(header => {
return header.key === binding.key;
});
}
function findMessage(businessObject) {
if (is$4(businessObject, 'bpmn:Event')) {
const eventDefinitions = businessObject.get('eventDefinitions');
if (!eventDefinitions || !eventDefinitions.length) {
return;
}
businessObject = eventDefinitions[0];
}
if (!businessObject) {
return;
}
return businessObject.get('messageRef');
}
function getDefaultValue(property) {
if (property.value !== undefined) {
return property.value;
}
if (property.generatedValue) {
const {
type
} = property.generatedValue;
if (type === 'uuid') {
return v4();
}
}
}
function createCommonjsModule(fn, module) {
return module = {
exports: {}
}, fn(module, module.exports), module.exports;
}
var hat_1 = createCommonjsModule(function (module) {
var hat = module.exports = function (bits, base) {
if (!base) base = 16;
if (bits === undefined) bits = 128;
if (bits <= 0) return '0';
var digits = Math.log(Math.pow(2, bits)) / Math.log(base);
for (var i = 2; digits === Infinity; i *= 2) {
digits = Math.log(Math.pow(2, bits / i)) / Math.log(base) * i;
}
var rem = digits - Math.floor(digits);
var res = '';
for (var i = 0; i < Math.floor(digits); i++) {
var x = Math.floor(Math.random() * base).toString(base);
res = x + res;
}
if (rem) {
var b = Math.pow(base, rem);
var x = Math.floor(Math.random() * b).toString(base);
res = x + res;
}
var parsed = parseInt(res, base);
if (parsed !== Infinity && parsed >= Math.pow(2, bits)) {
return hat(bits, base);
} else return res;
};
hat.rack = function (bits, base, expandBy) {
var fn = function (data) {
var iters = 0;
do {
if (iters++ > 10) {
if (expandBy) bits += expandBy;else throw new Error('too many ID collisions, use more bits');
}
var id = hat(bits, base);
} while (Object.hasOwnProperty.call(hats, id));
hats[id] = data;
return id;
};
var hats = fn.hats = {};
fn.get = function (id) {
return fn.hats[id];
};
fn.set = function (id, value) {
fn.hats[id] = value;
return fn;
};
fn.bits = bits || 128;
fn.base = base || 16;
return fn;
};
});
/**
* Create a new id generator / cache instance.
*
* You may optionally provide a seed that is used internally.
*
* @param {Seed} seed
*/
function Ids(seed) {
if (!(this instanceof Ids)) {
return new Ids(seed);
}
seed = seed || [128, 36, 1];
this._seed = seed.length ? hat_1.rack(seed[0], seed[1], seed[2]) : seed;
}
/**
* Generate a next id.
*
* @param {Object} [element] element to bind the id to
*
* @return {String} id
*/
Ids.prototype.next = function (element) {
return this._seed(element || true);
};
/**
* Generate a next id with a given prefix.
*
* @param {Object} [element] element to bind the id to
*
* @return {String} id
*/
Ids.prototype.nextPrefixed = function (prefix, element) {
var id;
do {
id = prefix + this.next(true);
} while (this.assigned(id));
// claim {prefix}{random}
this.claim(id, element);
// return
return id;
};
/**
* Manually claim an existing id.
*
* @param {String} id
* @param {String} [element] element the id is claimed by
*/
Ids.prototype.claim = function (id, element) {
this._seed.set(id, element || true);
};
/**
* Returns true if the given id has already been assigned.
*
* @param {String} id
* @return {Boolean}
*/
Ids.prototype.assigned = function (id) {
return this._seed.get(id) || false;
};
/**
* Unclaim an id.
*
* @param {String} id the id to unclaim
*/
Ids.prototype.unclaim = function (id) {
delete this._seed.hats[id];
};
/**
* Clear all claimed ids.
*/
Ids.prototype.clear = function () {
var hats = this._seed.hats,
id;
for (id in hats) {
this.unclaim(id);
}
};
/**
* Create a new element and set its parent.
*
* @param {String} elementType of the new element
* @param {Object} properties of the new element in key-value pairs
* @param {moddle.object} parent of the new element
* @param {BpmnFactory} factory which creates the new element
*
* @returns {djs.model.Base} element which is created
*/
function createElement$1(elementType, properties, parent, factory) {
const element = factory.create(elementType, properties);
if (parent) {
element.$parent = parent;
}
return element;
}
/**
* generate a semantic id with given prefix
*/
function nextId$1(prefix) {
const ids = new Ids([32, 32, 1]);
return ids.nextPrefixed(prefix);
}
function getRoot$2(businessObject) {
let parent = businessObject;
while (parent.$parent) {
parent = parent.$parent;
}
return parent;
}
function filterElementsByType$1(objectList, type) {
const list = objectList || [];
return list.filter(element => is$4(element, type));
}
function findRootElementsByType$1(businessObject, referencedType) {
const root = getRoot$2(businessObject);
return filterElementsByType$1(root.get('rootElements'), referencedType);
}
function findRootElementById$1(businessObject, type, id) {
const elements = findRootElementsByType$1(businessObject, type);
return elements.find(element => element.id === id);
}
/**
* Create an input parameter representing the given
* binding and value.
*
* @param {PropertyBinding} binding
* @param {String} value
* @param {BpmnFactory} bpmnFactory
*
* @return {ModdleElement}
*/
function createInputParameter$1(binding, value, bpmnFactory) {
const {
name
} = binding;
return bpmnFactory.create('zeebe:Input', {
source: value,
target: name
});
}
/**
* Create an output parameter representing the given
* binding and value.
*
* @param {PropertyBinding} binding
* @param {String} value
* @param {BpmnFactory} bpmnFactory
*
* @return {ModdleElement}
*/
function createOutputParameter$1(binding, value, bpmnFactory) {
const {
source
} = binding;
return bpmnFactory.create('zeebe:Output', {
source,
target: value
});
}
/**
* Create a task header representing the given
* binding and value.
*
* @param {PropertyBinding} binding
* @param {String} value
* @param {BpmnFactory} bpmnFactory
*
* @return {ModdleElement}
*/
function createTaskHeader(binding, value, bpmnFactory) {
const {
key
} = binding;
return bpmnFactory.create('zeebe:Header', {
key,
value
});
}
/**
* Create a task definition representing the given value.
*
* @param {object} attrs
* @param {BpmnFactory} bpmnFactory
*
* @return {ModdleElement}
*/
function createTaskDefinition(attrs = {}, bpmnFactory) {
return bpmnFactory.create('zeebe:TaskDefinition', attrs);
}
/**
* Create zeebe:Property from the given binding.
*
* @param {PropertyBinding} binding
* @param {String} value
* @param {BpmnFactory} bpmnFactory
*
* @return {ModdleElement}
*/
function createZeebeProperty(binding, value = '', bpmnFactory) {
const {
name
} = binding;
return bpmnFactory.create('zeebe:Property', {
name,
value
});
}
/**
* Create a called element representing the given value.
*
* @param {object} attrs
* @param {BpmnFactory} bpmnFactory
*
* @return {ModdleElement}
*/
function createCalledElement(attrs = {}, bpmnFactory) {
return bpmnFactory.create('zeebe:CalledElement', attrs);
}
/**
* Retrieves whether an element should be updated for a given property.
*
* That matches once
* a) the property value is not empty, or
* b) the property is not optional
*
* @param {String} value
* @param {Object} property
* @returns {Boolean}
*/
function shouldUpdate(value, property) {
const {
optional
} = property;
return value || !optional;
}
/**
* Gets or, in case not existent, creates extension element for given element.
*
* @param {djs.model.Base} element
* @param {String} type
* @param {BpmnFactory} bpmnFactory
* @returns {ModdleElement}
*/
function ensureExtension(element, type, bpmnFactory) {
const businessObject = getBusinessObject$1(element);
let extensionElements = businessObject.get('extensionElements');
if (!extensionElements) {
extensionElements = createElement$1('bpmn:ExtensionElements', {}, businessObject, bpmnFactory);
businessObject.set('extensionElements', extensionElements);
}
let extension = findExtension$1(extensionElements, type);
if (!extension) {
extension = bpmnFactory.create(type);
extension.$parent = extensionElements;
extensionElements.get('values').push(extension);
}
return extension;
}
const PRIMITIVE_MODDLE_TYPES$1 = ['Boolean', 'Integer', 'String'];
function getPropertyValue$1(element, property, scope) {
let businessObject = getBusinessObject$1(element);
const defaultValue = '';
const {
binding
} = property;
const {
name,
property: bindingProperty,
type
} = binding;
// property
if (type === 'property') {
const value = businessObject.get(name);
if (!isUndefined$1(value)) {
return value;
}
return defaultValue;
}
// zeebe:taskDefinition
if (TASK_DEFINITION_TYPES.includes(type)) {
const taskDefinition = findExtension$1(businessObject, 'zeebe:TaskDefinition');
if (taskDefinition) {
if (type === ZEEBE_TASK_DEFINITION_TYPE_TYPE) {
return taskDefinition.get('type');
} else if (type === ZEEBE_TASK_DEFINITION) {
return taskDefinition.get(bindingProperty);
}
}
return defaultValue;
}
if (IO_BINDING_TYPES$1.includes(type)) {
const ioMapping = findExtension$1(businessObject, 'zeebe:IoMapping');
if (!ioMapping) {
return defaultValue;
}
// zeebe:Input
if (type === ZEBBE_INPUT_TYPE) {
const inputParameter = findInputParameter$1(ioMapping, binding);
if (inputParameter) {
return inputParameter.get('source');
}
return defaultValue;
}
// zeebe:Output
if (type === ZEEBE_OUTPUT_TYPE) {
const outputParameter = findOutputParameter$1(ioMapping, binding);
if (outputParameter) {
return outputParameter.get('target');
}
return defaultValue;
}
}
// zeebe:taskHeaders
if (type === ZEEBE_TASK_HEADER_TYPE) {
const taskHeaders = findExtension$1(businessObject, 'zeebe:TaskHeaders');
if (!taskHeaders) {
return defaultValue;
}
const header = findTaskHeader(taskHeaders, binding);
if (header) {
return header.get('value');
}
return defaultValue;
}
// zeebe:Property
if (type === ZEEBE_PROPERTY_TYPE) {
const zeebeProperties = findExtension$1(businessObject, 'zeebe:Properties');
if (zeebeProperties) {
const zeebeProperty = findZeebeProperty(zeebeProperties, binding);
if (zeebeProperty) {
return zeebeProperty.get('value');
}
}
return defaultValue;
}
// bpmn:Message#property
if (type === MESSAGE_PROPERTY_TYPE) {
const message = findMessage(businessObject);
const value = message ? message.get(name) : undefined;
if (!isUndefined$1(value)) {
return value;
}
return defaultValue;
}
// bpmn:Message#zeebe:subscription#property
if (type === MESSAGE_ZEEBE_SUBSCRIPTION_PROPERTY_TYPE) {
const message = findMessage(businessObject);
if (message) {
const subscription = findExtension$1(message, 'zeebe:Subscription');
const value = subscription ? subscription.get(name) : undefined;
if (!isUndefined$1(value)) {
return subscription.get(name);
}
}
return defaultValue;
}
// zeebe:calledElement
if (type === ZEEBE_CALLED_ELEMENT) {
const calledElement = findExtension$1(businessObject, 'zeebe:CalledElement');
return calledElement ? calledElement.get(bindingProperty) : defaultValue;
}
// should never throw as templates are validated beforehand
throw unknownBindingError$1(element, property);
}
const NO_OP = null;
function setPropertyValue(bpmnFactory, commandStack, element, property, value) {
let businessObject = getBusinessObject$1(element);
const {
binding
} = property;
const {
name,
type
} = binding;
let extensionElements;
let propertyValue;
const commands = [];
const context = {
element,
property
};
// ensure message exists
if (MESSAGE_BINDING_TYPES.includes(type)) {
if (is$4(businessObject, 'bpmn:Event')) {
businessObject = businessObject.get('eventDefinitions')[0];
}
let message = findMessage(businessObject);
if (!message) {
message = bpmnFactory.create('bpmn:Message', {
'zeebe:modelerTemplate': getTemplateId$1(element)
});
commands.push({
cmd: 'element.updateModdleProperties',
context: {
...context,
moddleElement: businessObject,
properties: {
messageRef: message
}
}
});
}
businessObject = message;
}
// ensure extension elements
if (EXTENSION_BINDING_TYPES$1.includes(type)) {
extensionElements = businessObject.get('extensionElements');
if (!extensionElements) {
extensionElements = createElement$1('bpmn:ExtensionElements', null, businessObject, bpmnFactory);
commands.push({
cmd: 'element.updateModdleProperties',
context: {
...context,
moddleElement: businessObject,
properties: {
extensionElements
}
}
});
} else {
commands.push(NO_OP);
}
}
// property
if (PROPERTY_BINDING_TYPES.includes(type)) {
const propertyDescriptor = businessObject.$descriptor.propertiesByName[name];
// if property not created yet
if (!propertyDescriptor) {
// make sure we create the property
propertyValue = value || '';
} else {
const {
type: propertyType
} = propertyDescriptor;
// do not override non-primitive types
if (!PRIMITIVE_MODDLE_TYPES$1.includes(propertyType)) {
throw new Error(`cannot set property of type <${propertyType}>`);
}
if (propertyType === 'Boolean') {
propertyValue = !!value;
} else if (propertyType === 'Integer') {
propertyValue = parseInt(value, 10);
if (isNaN(propertyValue)) {
// do not set NaN value
propertyValue = undefined;
}
} else {
// make sure we don't remove the property
propertyValue = value || '';
}
}
if (!isUndefined$1(propertyValue)) {
commands.push({
cmd: 'element.updateModdleProperties',
context: {
...context,
moddleElement: businessObject,
properties: {
[name]: propertyValue
}
}
});
} else {
commands.push(NO_OP);
}
}
// zeebe:taskDefinition
if (TASK_DEFINITION_TYPES.includes(type)) {
const oldTaskDefinition = findExtension$1(extensionElements, 'zeebe:TaskDefinition'),
propertyName = getTaskDefinitionPropertyName(binding),
properties = {
[propertyName]: value || ''
};
if (oldTaskDefinition) {
commands.push({
cmd: 'element.updateModdleProperties',
context: {
...context,
properties,
moddleElement: oldTaskDefinition
}
});
} else {
const newTaskDefinition = createTaskDefinition(properties, bpmnFactory);
newTaskDefinition.$parent = businessObject;
const values = extensionElements.get('values');
commands.push({
cmd: 'element.updateModdleProperties',
context: {
...context,
moddleElement: extensionElements,
properties: {
values: [...values, newTaskDefinition]
}
}
});
}
}
if (IO_BINDING_TYPES$1.includes(type)) {
let ioMapping = findExtension$1(extensionElements, 'zeebe:IoMapping');
if (!ioMapping) {
ioMapping = createElement$1('zeebe:IoMapping', null, businessObject, bpmnFactory);
commands.push({
cmd: 'element.updateModdleProperties',
context: {
...context,
moddleElement: extensionElements,
properties: {
values: [...extensionElements.get('values'), ioMapping]
}
}
});
}
// zeebe:Input
if (type === ZEBBE_INPUT_TYPE) {
const oldZeebeInputParameter = findInputParameter$1(ioMapping, binding);
const values = ioMapping.get('inputParameters').filter(value => value !== oldZeebeInputParameter);
// do not persist empty parameters when configured as <optional>
if (shouldUpdate(value, property)) {
const newZeebeInputParameter = createInputParameter$1(binding, value, bpmnFactory);
values.push(newZeebeInputParameter);
}
commands.push({
cmd: 'element.updateModdleProperties',
context: {
...context,
moddleElement: ioMapping,
properties: {
inputParameters: [...values]
}
}
});
}
// zeebe:Output
if (type === ZEEBE_OUTPUT_TYPE) {
const oldZeebeOutputParameter = findOutputParameter$1(ioMapping, binding);
const values = ioMapping.get('outputParameters').filter(value => value !== oldZeebeOutputParameter);
// do not persist empty parameters when configured as <optional>
if (shouldUpdate(value, property)) {
const newZeebeOutputParameter = createOutputParameter$1(binding, value, bpmnFactory);
values.push(newZeebeOutputParameter);
}
commands.push({
cmd: 'element.updateModdleProperties',
context: {
...context,
moddleElement: ioMapping,
properties: {
'outputParameters': [...values]
}
}
});
}
}
// zeebe:taskHeaders
if (type === ZEEBE_TASK_HEADER_TYPE) {
let taskHeaders = findExtension$1(extensionElements, 'zeebe:TaskHeaders');
if (!taskHeaders) {
taskHeaders = createElement$1('zeebe:TaskHeaders', null, businessObject, bpmnFactory);
commands.push({
cmd: 'element.updateModdleProperties',
context: {
...context,
moddleElement: extensionElements,
properties: {
values: [...extensionElements.get('values'), taskHeaders]
}
}
});
}
const oldTaskHeader = findTaskHeader(taskHeaders, binding);
const values = taskHeaders.get('values').filter(value => value !== oldTaskHeader);
// do not persist task headers with empty value
if (!value) {
commands.push({
cmd: 'element.updateModdleProperties',
context: {
...context,
moddleElement: taskHeaders,
properties: {
values
}
}
});
} else {
const newTaskHeader = createTaskHeader(binding, value, bpmnFactory);
commands.push({
cmd: 'element.updateModdleProperties',
context: {
...context,
moddleElement: taskHeaders,
properties: {
values: [...values, newTaskHeader]
}
}
});
}
}
// zeebe:Property
if (type === ZEEBE_PROPERTY_TYPE) {
let zeebeProperties = findExtension$1(extensionElements, 'zeebe:Properties');
if (!zeebeProperties) {
zeebeProperties = createElement$1('zeebe:Properties', null, businessObject, bpmnFactory);
commands.push({
cmd: 'element.updateModdleProperties',
context: {
element,
moddleElement: extensionElements,
properties: {
values: [...extensionElements.get('values'), zeebeProperties]
}
}
});
}
const oldZeebeProperty = findZeebeProperty(zeebeProperties, binding);
const properties = zeebeProperties.get('properties').filter(property => property !== oldZeebeProperty);
if (shouldUpdate(value, property)) {
const newZeebeProperty = createZeebeProperty(binding, value, bpmnFactory);
properties.push(newZeebeProperty);
}
commands.push({
cmd: 'element.updateModdleProperties',
context: {
element,
moddleElement: zeebeProperties,
properties: {
properties
}
}
});
}
// bpmn:Message#zeebe:subscription#property
if (type === MESSAGE_ZEEBE_SUBSCRIPTION_PROPERTY_TYPE) {
let subscription = findExtension$1(extensionElements, 'zeebe:Subscription');
const properties = {
[name]: value || ''
};
if (subscription) {
commands.push({
cmd: 'element.updateModdleProperties',
context: {
element,
properties,
moddleElement: subscription
}
});
} else {
subscription = createElement$1('zeebe:Subscription', properties, extensionElements, bpmnFactory);
commands.push({
cmd: 'element.updateModdleProperties',
context: {
...context,
moddleElement: extensionElements,
properties: {
values: [...extensionElements.get('values'), subscription]
}
}
});
}
}
// zeebe:calledElement
if (type === ZEEBE_CALLED_ELEMENT) {
let calledElement = findExtension$1(element, 'zeebe:CalledElement');
const propertyName = binding.property;
const properties = {
[propertyName]: value || ''
};
if (calledElement) {
commands.push({
cmd: 'element.updateModdleProperties',
context: {
element,
properties,
moddleElement: calledElement
}
});
} else {
calledElement = createElement$1('zeebe:CalledElement', properties, extensionElements, bpmnFactory);
commands.push({
cmd: 'element.updateModdleProperties',
context: {
...context,
moddleElement: extensionElements,
properties: {
values: [...extensionElements.get('values'), calledElement]
}
}
});
}
}
if (commands.length) {
const commandsToExecute = commands.filter(command => command !== NO_OP);
commandsToExecute.length && commandStack.execute('properties-panel.multi-command-executor', commandsToExecute);
return;
}
// should never throw as templates are validated beforehand
throw unknownBindingError$1(element, property);
}
function validateProperty(value, property, translate$1 = translate) {