camunda-bpmn-js 5.14.0 → 5.14.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -143768,1212 +143768,1219 @@
143768
143768
  });
143769
143769
  };
143770
143770
 
143771
- class CachedValue {
143772
- constructor(generatorFunction) {
143773
- this._generate = generatorFunction;
143774
- this.value = null;
143775
- this.valid = false;
143776
- }
143777
-
143778
- invalidate() {
143779
- this.valid = false;
143780
- }
143781
-
143782
- get() {
143783
- if (!this.valid) {
143784
- this.value = this._generate();
143785
- this.valid = true;
143786
- }
143787
-
143788
- return this.value;
143789
- }
143790
- }
143771
+ class CachedValue {
143772
+ constructor(generatorFunction) {
143773
+ this._generate = generatorFunction;
143774
+ this.value = null;
143775
+ this.valid = false;
143776
+ }
143791
143777
 
143792
- function hasOutputMappings(element) {
143793
- return !!getOutputParameters(element).length;
143794
- }
143795
-
143796
- function hasInputParameter(element, name) {
143797
- return getInputParameters(element).find(function(input) {
143798
- return (
143799
- input.target === name || // zeebe
143800
- input.name === name // camunda
143801
- );
143802
- });
143803
- }
143804
-
143805
- function getExtensionElementsList(businessObject, type = undefined) {
143806
- const extensionElements = businessObject.get('extensionElements');
143807
-
143808
- if (!extensionElements) {
143809
- return [];
143810
- }
143811
-
143812
- const values = extensionElements.get('values');
143813
-
143814
- if (!values || !values.length) {
143815
- return [];
143816
- }
143817
-
143818
- if (type) {
143819
- return values.filter(value => is$4(value, type));
143820
- }
143821
-
143822
- return values;
143823
- }
143824
-
143825
- // helpers //////////
143826
-
143827
- function getInputParameters(element) {
143828
- return getParameters(element, 'inputParameters');
143829
- }
143830
-
143831
- function getOutputParameters(element) {
143832
- return getParameters(element, 'outputParameters');
143833
- }
143834
-
143835
- function getInputOutput(element) {
143836
- return (
143837
- (getExtensionElements$2(element, 'zeebe:IoMapping'))[0] ||
143838
- (getExtensionElements$2(element, 'camunda:InputOutput'))[0]
143839
- );
143840
- }
143841
-
143842
- function getParameters(element, property) {
143843
- var inputOutput = getInputOutput(element);
143844
-
143845
- return (inputOutput && inputOutput.get(property)) || [];
143846
- }
143847
-
143848
- function getExtensionElements$2(element, type) {
143849
- var elements = [];
143850
- var extensionElements = element.get('extensionElements');
143851
-
143852
- if (typeof extensionElements !== 'undefined') {
143853
- var extensionValues = extensionElements.get('values');
143854
-
143855
- if (typeof extensionValues !== 'undefined') {
143856
- elements = filter(extensionValues, function(value) {
143857
- return is$4(value, type);
143858
- });
143859
- }
143860
- }
143861
-
143862
- return elements;
143778
+ invalidate() {
143779
+ this.valid = false;
143780
+ }
143781
+
143782
+ get() {
143783
+ if (!this.valid) {
143784
+ this.value = this._generate();
143785
+ this.valid = true;
143786
+ }
143787
+
143788
+ return this.value;
143789
+ }
143863
143790
  }
143864
143791
 
143865
- function getScope(element, globalScope, variableName) {
143866
- var parents = getParents(element);
143867
-
143868
- if (hasOutputMappings(element)) {
143869
- return element;
143870
- }
143871
-
143872
- var scopedParent = parents.find(function(parent) {
143873
- return (
143874
- is$4(parent, 'bpmn:SubProcess') && hasInputParameter(parent, variableName)
143875
- );
143876
- });
143877
-
143878
- return scopedParent ? scopedParent : globalScope;
143879
- }
143880
-
143881
- function getParents(element) {
143882
- var parents = [];
143883
- var current = element;
143884
-
143885
- while (current.$parent) {
143886
- parents.push(current.$parent);
143887
- current = current.$parent;
143888
- }
143889
-
143890
- return parents;
143792
+ function hasOutputMappings(element) {
143793
+ return !!getOutputParameters(element).length;
143891
143794
  }
143892
143795
 
143893
- /**
143894
- * @typedef {Object} AdditionalVariable
143895
- * @property {string} name The name of the variable
143896
- * @property {string} [type] The type of the variable
143897
- * @property {string} [info] A description of the variable displayed as a tooltip
143898
- * @property {boolean} [isList] whether the variable is a list
143899
- * @property {Array<AdditionalVariable>} [entries] If the variable is a context, this contains the entries of the context
143900
- * @property {djs.model.Base} [scope] The scope of the variable, by default it is the container element of the element the variable is created from
143901
- */
143902
-
143903
- /**
143904
- * @typedef {AdditionalVariable} ProcessVariable
143905
- * @property {Array<ModdleElement>} origin
143906
- * @property {ModdleElement} scope
143907
- * @property {Array<Object>} provider
143908
- */
143909
-
143910
- /**
143911
- * Base Class that handles additional variable extractors, variable parsing and caching.
143912
- */
143913
- class BaseVariableResolver {
143914
- constructor(eventBus, bpmnjs) {
143915
- this.providers = [];
143916
- this._eventBus = eventBus;
143917
- this._bpmnjs = bpmnjs;
143918
-
143919
- this.rawVariables = new CachedValue(this._generateRawVariables.bind(this));
143920
- this.parsedVariables = new CachedValue(async () => {
143921
-
143922
- const rawVariables = await this.getRawVariables();
143923
- const context = { variables: rawVariables };
143924
-
143925
- eventBus.fire('variableResolver.parseVariables', context);
143926
-
143927
- return context.variables;
143928
- });
143929
-
143930
- eventBus.on([ 'commandStack.changed', 'diagram.clear', 'import.done', 'variables.changed' ], () => {
143931
- this.invalidateCache();
143932
- });
143933
-
143934
- eventBus.on('variableResolver.parseVariables', (e, context) => {
143935
- context.variables = this._parseVariables(context.variables);
143936
- });
143937
- }
143938
-
143939
- /**
143940
- * To be implemented by a subclass. This should be an instance of `getProcessVariables` from `@bpmn-io/extract-process-variables`,
143941
- * either C7 or C8.
143942
- *
143943
- * @returns {Promise<Array<ProcessVariable>>}
143944
- */
143945
- _baseExtractor() {
143946
- return [];
143947
- }
143948
-
143949
-
143950
- /**
143951
- * Returns an Object of all variables that are available in the current diagram,
143952
- * mapped to the respective scope.
143953
- * Variables with the same name are NOT merged together. Use this function to
143954
- * run linting, e.g. to check for conflicting variable schemas.
143955
- *
143956
- * The result is cached until the diagram changes.
143957
- *
143958
- * @async
143959
- * @returns {Object} rawVariables
143960
- * @returns {Array<ProcessVariable>} rawVariables.<scope>
143961
- */
143962
- async getRawVariables() {
143963
- return await this.rawVariables.get();
143964
- }
143965
-
143966
- /**
143967
- * Returns an array of all variables that are available in the current diagram.
143968
- * Variables with the same name are NOT merged together. Use this function to
143969
- * run linting, e.g. to check for conflicting variable schemas.
143970
- *
143971
- * Use this function if you need all availables for all root elements. To filter for scope,
143972
- * use `getProcessVariables` or `getVariablesForElement`
143973
- *
143974
- * The result is cached until the diagram changes.
143975
- *
143976
- * @async
143977
- * @returns {Object} rawVariables
143978
- * @returns {Array<ProcessVariable>} rawVariables.<rootElement>
143979
- */
143980
- async getVariables() {
143981
- return await this.parsedVariables.get();
143982
- }
143983
-
143984
- /**
143985
- * Force the cache to be invalidated an the variable extractors to be called
143986
- * again the next time `getVariables` is called.
143987
- */
143988
- invalidateCache() {
143989
- this.rawVariables.invalidate();
143990
- this.parsedVariables.invalidate();
143991
- }
143992
-
143993
- /**
143994
- * Calls the baseExtractor and maps variables to the respective root element.
143995
- * Cf. `getRawVariables`
143996
- *
143997
- * @async
143998
- * @returns {Object} rawVariables
143999
- * @returns {Array<ProcessVariable>} rawVariables.<scope>
144000
- */
144001
- async _generateRawVariables() {
144002
- const bpmnjs = this._bpmnjs;
144003
-
144004
- const variables = {};
144005
-
144006
- const workerTasks = bpmnjs.getDefinitions().get('rootElements').map(async element => {
144007
-
144008
- const elementVariables = await this._baseExtractor(element, [ this._extractor.bind(this) ]);
144009
-
144010
- // Annotate variables with extractor information
144011
- variables[element.id] = elementVariables.map(variable => {
144012
- if (!variable.provider) {
144013
- variable.provider = [ this._baseExtractor ];
144014
- }
144015
-
144016
- return variable;
144017
- });
144018
- });
144019
-
144020
- await Promise.all(workerTasks);
144021
-
144022
- return variables;
144023
- }
144024
-
144025
-
144026
- /**
144027
- * Parses the list of all variables and checks for duplicates. If duplicates are found, the schemas are merged
144028
- * into a single variable.
144029
- * Also maps the attribute `variable.type` to `variable.detail` for the feel editor to display it.
144030
- *
144031
- * Cf. `getVariables`
144032
- *
144033
- * @async
144034
- * @param {Object} rawVariables
144035
- * @param {Array<ProcessVariable>} rawVariables[scope]
144036
- * @returns {Object} parsedVariables
144037
- * @returns {Array<ProcessVariable>} parsedVariables[scope]
144038
- */
144039
- _parseVariables(rawVariables) {
144040
- const parsedVariables = {};
144041
- for (const key in rawVariables) {
144042
- const variables = rawVariables[key];
144043
-
144044
- const mergedVariables = [];
144045
-
144046
- variables.forEach(variable => {
144047
- const existingVariable = mergedVariables.find(v =>
144048
- v.name === variable.name && v.scope === variable.scope
144049
- );
144050
-
144051
- if (existingVariable) {
144052
- merge('origin', existingVariable, variable);
144053
- merge('provider', existingVariable, variable);
144054
- mergeEntries(existingVariable, variable);
144055
- } else {
144056
- mergedVariables.push(variable);
144057
- }
144058
- });
144059
-
144060
- mapToEditorFormat(mergedVariables);
144061
-
144062
- parsedVariables[key] = mergedVariables;
144063
- }
144064
-
144065
- return parsedVariables;
144066
- }
144067
-
144068
- /**
144069
- * Callback used by `@bpmn-io/extract-process-variables`. It adds additional information from the <AdditionalVariable>
144070
- * returned from the providers to the <ProcessVariable> that is used by the resolver.
144071
- *
144072
- * It does not have a return value, the variables are added as a side effect to the `context.processVariables` array
144073
- *
144074
- * @async
144075
- * @param {Object} context
144076
- * @param {Array<ModdleElement>} context.elements
144077
- * @param {ModdleElement} context.containerElement
144078
- * @param {Array<ProcessVariable>} context.processVariables
144079
- */
144080
- async _extractor(context) {
144081
- const {
144082
- elements,
144083
- containerElement,
144084
- processVariables
144085
- } = context;
144086
-
144087
- const self = this;
144088
-
144089
- const workerTasks = elements.flatMap((element) => {
144090
- return self.providers.map(async (provider) => {
144091
- const newVariables = await provider.getVariables(element);
144092
-
144093
- if (!newVariables) {
144094
- return;
144095
- }
144096
-
144097
- // add scope and origin to variables
144098
- newVariables.forEach(variable => {
144099
- processVariables.push({
144100
- ...cloneVariable(variable),
144101
- origin: [ element ],
144102
- scope: variable.scope || getScope(element, containerElement, variable.name),
144103
- provider: [ provider ]
144104
- });
144105
- });
144106
- });
144107
- });
144108
-
144109
- await Promise.all(workerTasks);
144110
- }
144111
-
144112
- /**
144113
- * Add a new VariableProvider. This will be used the next time `getVariables` is called.
144114
- *
144115
- * @param {VariableProvider} provider
144116
- */
144117
- registerProvider(provider) {
144118
- this.providers.push(provider);
144119
- this.invalidateCache();
144120
- }
144121
-
144122
- /**
144123
- * Returns all variables for the given root element.
144124
- *
144125
- * @async
144126
- * @param {ModdleElement} element
144127
- * @returns {Array<ProcessVariable>} variables
144128
- */
144129
- async getProcessVariables(element) {
144130
- const bo = getBusinessObject$2(element);
144131
-
144132
- const allVariables = await this.getVariables();
144133
- return allVariables[bo.id] || [];
144134
- }
144135
-
144136
- /**
144137
- * Returns all variables in the scope of the given element.
144138
- *
144139
- * @async
144140
- * @param {ModdleElement} element
144141
- * @returns {Array<ProcessVariable>} variables
144142
- */
144143
- async getVariablesForElement(element) {
144144
- const bo = getBusinessObject$2(element);
144145
-
144146
- const root = getRootElement(bo);
144147
- const allVariables = await this.getProcessVariables(root);
144148
-
144149
- // (1) get variables for given scope
144150
- var scopeVariables = allVariables.filter(function(variable) {
144151
- return variable.scope.id === bo.id;
144152
- });
144153
-
144154
- // (2) get variables for parent scopes
144155
- var parents = getParents(bo);
144156
-
144157
- var parentsScopeVariables = allVariables.filter(function(variable) {
144158
- return parents.find(function(parent) {
144159
- return parent.id === variable.scope.id;
144160
- });
144161
- });
144162
-
144163
- const reversedVariables = [ ...scopeVariables, ...parentsScopeVariables ].reverse();
144164
-
144165
- const seenNames = new Set();
144166
-
144167
- return reversedVariables.filter(variable => {
144168
-
144169
- // if external variable, keep
144170
- if (variable.provider.find(extractor => extractor !== this._baseExtractor)) {
144171
- return true;
144172
- }
144173
-
144174
- // if not external, keep only the first occurrence of each name
144175
- if (!seenNames.has(variable.name)) {
144176
- seenNames.add(variable.name);
144177
-
144178
- return true;
144179
- }
144180
-
144181
- return false;
144182
- });
144183
- }
144184
- }
144185
-
144186
- BaseVariableResolver.$inject = [ 'eventBus', 'bpmnjs' ];
144187
-
144188
-
144189
- // helpers //////////////////////
144190
-
144191
- function getRootElement(element) {
144192
- const businessObject = getBusinessObject$2(element);
144193
-
144194
- if (is$4(businessObject, 'bpmn:Participant')) {
144195
- return businessObject.processRef;
144196
- }
144197
-
144198
- if (is$4(businessObject, 'bpmn:Process')) {
144199
- return businessObject;
144200
- }
144201
-
144202
- let parent = businessObject;
144203
-
144204
- while (parent.$parent && !is$4(parent, 'bpmn:Process')) {
144205
- parent = parent.$parent;
144206
- }
144207
-
144208
- return parent;
144209
- }
144210
-
144211
- function merge(property, target, source) {
144212
- if (!source[property]) {
144213
- source[property] = [];
144214
- }
144215
-
144216
- if (!target[property]) {
144217
- target[property] = [];
144218
- }
144219
-
144220
- const propertiesToAdd = source[property].filter(o => !target[property].includes(o));
144221
-
144222
- target[property].push(...propertiesToAdd);
144223
- }
144224
-
144225
- function mergeEntries(target, source, visited = []) {
144226
- if (visited.includes(source) || visited.includes(target)) {
144227
- return;
144228
- }
144229
- visited.push(source);
144230
- visited.push(target);
144231
-
144232
- target.type = extendList(target.type, source.type, '|');
144233
- target.info = extendList(target.info, source.info, '\n');
144234
- target.isList = !!target.isList === !!source.isList ? target.isList : 'optional';
144235
-
144236
- if (!source.entries) {
144237
- return;
144238
- }
144239
-
144240
- if (!target.entries) {
144241
- target.entries = [];
144242
- }
144243
-
144244
- source.entries.forEach(variable => {
144245
- const existingEntry = target.entries.find(e => e.name === variable.name);
144246
-
144247
- if (existingEntry) {
144248
- mergeEntries(existingEntry, variable, visited);
144249
- } else {
144250
- target.entries.push(variable);
144251
- }
144252
- });
144253
- }
144254
-
144255
- const extendList = (target, source, separator) => {
144256
- if (!target || target === source) {
144257
- return source;
144258
- } else {
144259
- const existingTypes = target.split(separator);
144260
- if (!existingTypes.includes(source)) {
144261
- existingTypes.push(source);
144262
- }
144263
- return existingTypes.join(separator);
144264
- }
144265
- };
144266
-
144267
- function mapToEditorFormat(variables) {
144268
- if (!variables) {
144269
- return;
144270
- }
144271
-
144272
- variables.forEach(variable => {
144273
- variable.detail = variable.type;
144274
- mapToEditorFormat(variable.entries);
144275
- });
144276
- }
144277
-
144278
- function cloneVariable(variable) {
144279
- const newVariable = { ...variable };
144280
-
144281
- if (newVariable.entries) {
144282
- newVariable.entries = newVariable.entries.map(cloneVariable);
144283
- }
144284
-
144285
- return newVariable;
143796
+ function hasInputParameter(element, name) {
143797
+ return getInputParameters(element).find(function(input) {
143798
+ return (
143799
+ input.target === name || // zeebe
143800
+ input.name === name // camunda
143801
+ );
143802
+ });
144286
143803
  }
144287
143804
 
144288
- class EntriesContext extends VariableContext$1 {
144289
- constructor(value = { entries: {} }) {
144290
- super(value);
144291
-
144292
- this.value.entries = this.value.entries || {};
144293
-
144294
- const context = this.value;
144295
-
144296
- for (const key in context.entries) {
144297
- const entry = context.entries[key];
144298
-
144299
- if (entry instanceof EntriesContext) {
144300
- continue;
144301
- }
144302
-
144303
- context.entries[key] = this.constructor.of(context.entries[key]);
144304
- }
144305
- }
144306
-
144307
- getKeys() {
144308
- return Object.keys(this.value.entries);
144309
- }
144310
-
144311
- get(key) {
144312
- const value = this.value.entries[key];
144313
-
144314
- if (!value) {
144315
- return value;
144316
- }
144317
-
144318
- if (value.atomic) {
144319
- return value.atomicValue;
144320
- }
144321
-
144322
- return value;
144323
- }
144324
-
144325
- set(key, value) {
144326
- return this.constructor.of(
144327
- {
144328
- ...this.value,
144329
- entries: {
144330
- ...this.value.entries,
144331
- [key]: value
144332
- }
144333
- }
144334
- );
144335
- }
144336
-
144337
- static of(...contexts) {
144338
- const unwrap = (context) => {
144339
-
144340
- if (
144341
- this.isAtomic(context)
144342
- ) {
144343
- if (context instanceof this) {
144344
- return context.value;
144345
- }
144346
-
144347
- return {
144348
- atomic: true,
144349
- atomicValue: context
144350
- };
144351
- }
144352
-
144353
- return { ...context };
144354
- };
144355
-
144356
- const merged = contexts.reduce((merged, context) => {
144357
-
144358
- const {
144359
- entries = {},
144360
- ...rest
144361
- } = unwrap(context);
144362
-
144363
- return {
144364
- ...merged,
144365
- ...rest,
144366
- entries: {
144367
- ...merged.entries,
144368
- ...entries
144369
- }
144370
- };
144371
- }, {});
144372
-
144373
- return new this(merged);
144374
- }
143805
+ function getExtensionElementsList(businessObject, type = undefined) {
143806
+ const extensionElements = businessObject.get('extensionElements');
143807
+
143808
+ if (!extensionElements) {
143809
+ return [];
143810
+ }
143811
+
143812
+ const values = extensionElements.get('values');
143813
+
143814
+ if (!values || !values.length) {
143815
+ return [];
143816
+ }
143817
+
143818
+ if (type) {
143819
+ return values.filter(value => is$4(value, type));
143820
+ }
143821
+
143822
+ return values;
143823
+ }
143824
+
143825
+ // helpers //////////
143826
+
143827
+ function getInputParameters(element) {
143828
+ return getParameters(element, 'inputParameters');
143829
+ }
143830
+
143831
+ function getOutputParameters(element) {
143832
+ return getParameters(element, 'outputParameters');
143833
+ }
143834
+
143835
+ function getInputOutput(element) {
143836
+ return (
143837
+ (getExtensionElements$2(element, 'zeebe:IoMapping'))[0] ||
143838
+ (getExtensionElements$2(element, 'camunda:InputOutput'))[0]
143839
+ );
143840
+ }
143841
+
143842
+ function getParameters(element, property) {
143843
+ var inputOutput = getInputOutput(element);
143844
+
143845
+ return (inputOutput && inputOutput.get(property)) || [];
143846
+ }
143847
+
143848
+ function getExtensionElements$2(element, type) {
143849
+ var elements = [];
143850
+ var extensionElements = element.get('extensionElements');
143851
+
143852
+ if (typeof extensionElements !== 'undefined') {
143853
+ var extensionValues = extensionElements.get('values');
143854
+
143855
+ if (typeof extensionValues !== 'undefined') {
143856
+ elements = filter(extensionValues, function(value) {
143857
+ return is$4(value, type);
143858
+ });
143859
+ }
143860
+ }
143861
+
143862
+ return elements;
143863
+ }
143864
+
143865
+ function getScope(element, globalScope, variableName) {
143866
+ var parents = getParents(element);
143867
+
143868
+ if (hasOutputMappings(element)) {
143869
+ return element;
143870
+ }
143871
+
143872
+ var scopedParent = parents.find(function(parent) {
143873
+ return (
143874
+ is$4(parent, 'bpmn:SubProcess') && hasInputParameter(parent, variableName)
143875
+ );
143876
+ });
143877
+
143878
+ return scopedParent ? scopedParent : globalScope;
143879
+ }
143880
+
143881
+ function getParents(element) {
143882
+ var parents = [];
143883
+ var current = element;
143884
+
143885
+ while (current.$parent) {
143886
+ parents.push(current.$parent);
143887
+ current = current.$parent;
143888
+ }
143889
+
143890
+ return parents;
143891
+ }
143892
+
143893
+ /**
143894
+ * @typedef {Object} AdditionalVariable
143895
+ * @property {string} name The name of the variable
143896
+ * @property {string} [type] The type of the variable
143897
+ * @property {string} [info] A description of the variable displayed as a tooltip
143898
+ * @property {boolean} [isList] whether the variable is a list
143899
+ * @property {Array<AdditionalVariable>} [entries] If the variable is a context, this contains the entries of the context
143900
+ * @property {djs.model.Base} [scope] The scope of the variable, by default it is the container element of the element the variable is created from
143901
+ */
143902
+
143903
+ /**
143904
+ * @typedef {AdditionalVariable} ProcessVariable
143905
+ * @property {Array<ModdleElement>} origin
143906
+ * @property {ModdleElement} scope
143907
+ * @property {Array<Object>} provider
143908
+ */
143909
+
143910
+ /**
143911
+ * Base Class that handles additional variable extractors, variable parsing and caching.
143912
+ */
143913
+ class BaseVariableResolver {
143914
+ constructor(eventBus, bpmnjs) {
143915
+ this.providers = [];
143916
+ this._eventBus = eventBus;
143917
+ this._bpmnjs = bpmnjs;
143918
+
143919
+ this.rawVariables = new CachedValue(this._generateRawVariables.bind(this));
143920
+ this.parsedVariables = new CachedValue(async () => {
143921
+
143922
+ const rawVariables = await this.getRawVariables();
143923
+ const context = { variables: rawVariables };
143924
+
143925
+ eventBus.fire('variableResolver.parseVariables', context);
143926
+
143927
+ return context.variables;
143928
+ });
143929
+
143930
+ eventBus.on([ 'commandStack.changed', 'diagram.clear', 'import.done', 'variables.changed' ], () => {
143931
+ this.invalidateCache();
143932
+ });
143933
+
143934
+ eventBus.on('variableResolver.parseVariables', (e, context) => {
143935
+ context.variables = this._parseVariables(context.variables);
143936
+ });
143937
+ }
143938
+
143939
+ /**
143940
+ * To be implemented by a subclass. This should be an instance of `getProcessVariables` from `@bpmn-io/extract-process-variables`,
143941
+ * either C7 or C8.
143942
+ *
143943
+ * @returns {Promise<Array<ProcessVariable>>}
143944
+ */
143945
+ _baseExtractor() {
143946
+ return [];
143947
+ }
143948
+
143949
+
143950
+ /**
143951
+ * Returns an Object of all variables that are available in the current diagram,
143952
+ * mapped to the respective scope.
143953
+ * Variables with the same name are NOT merged together. Use this function to
143954
+ * run linting, e.g. to check for conflicting variable schemas.
143955
+ *
143956
+ * The result is cached until the diagram changes.
143957
+ *
143958
+ * @async
143959
+ * @returns {Object} rawVariables
143960
+ * @returns {Array<ProcessVariable>} rawVariables.<scope>
143961
+ */
143962
+ async getRawVariables() {
143963
+ return await this.rawVariables.get();
143964
+ }
143965
+
143966
+ /**
143967
+ * Returns an array of all variables that are available in the current diagram.
143968
+ * Variables with the same name are NOT merged together. Use this function to
143969
+ * run linting, e.g. to check for conflicting variable schemas.
143970
+ *
143971
+ * Use this function if you need all availables for all root elements. To filter for scope,
143972
+ * use `getProcessVariables` or `getVariablesForElement`
143973
+ *
143974
+ * The result is cached until the diagram changes.
143975
+ *
143976
+ * @async
143977
+ * @returns {Object} rawVariables
143978
+ * @returns {Array<ProcessVariable>} rawVariables.<rootElement>
143979
+ */
143980
+ async getVariables() {
143981
+ return await this.parsedVariables.get();
143982
+ }
143983
+
143984
+ /**
143985
+ * Force the cache to be invalidated an the variable extractors to be called
143986
+ * again the next time `getVariables` is called.
143987
+ */
143988
+ invalidateCache() {
143989
+ this.rawVariables.invalidate();
143990
+ this.parsedVariables.invalidate();
143991
+ }
143992
+
143993
+ /**
143994
+ * Calls the baseExtractor and maps variables to the respective root element.
143995
+ * Cf. `getRawVariables`
143996
+ *
143997
+ * @async
143998
+ * @returns {Object} rawVariables
143999
+ * @returns {Array<ProcessVariable>} rawVariables.<scope>
144000
+ */
144001
+ async _generateRawVariables() {
144002
+ const bpmnjs = this._bpmnjs;
144003
+
144004
+ const variables = {};
144005
+
144006
+ const workerTasks = bpmnjs.getDefinitions().get('rootElements').map(async element => {
144007
+
144008
+ const elementVariables = await this._baseExtractor(element, [ this._extractor.bind(this) ]);
144009
+
144010
+ // Annotate variables with extractor information
144011
+ variables[element.id] = elementVariables.map(variable => {
144012
+ if (!variable.provider) {
144013
+ variable.provider = [ this._baseExtractor ];
144014
+ }
144015
+
144016
+ return variable;
144017
+ });
144018
+ });
144019
+
144020
+ await Promise.all(workerTasks);
144021
+
144022
+ return variables;
144023
+ }
144024
+
144025
+
144026
+ /**
144027
+ * Parses the list of all variables and checks for duplicates. If duplicates are found, the schemas are merged
144028
+ * into a single variable.
144029
+ * Also maps the attribute `variable.type` to `variable.detail` for the feel editor to display it.
144030
+ *
144031
+ * Cf. `getVariables`
144032
+ *
144033
+ * @async
144034
+ * @param {Object} rawVariables
144035
+ * @param {Array<ProcessVariable>} rawVariables[scope]
144036
+ * @returns {Object} parsedVariables
144037
+ * @returns {Array<ProcessVariable>} parsedVariables[scope]
144038
+ */
144039
+ _parseVariables(rawVariables) {
144040
+ const parsedVariables = {};
144041
+ for (const key in rawVariables) {
144042
+ const variables = rawVariables[key];
144043
+
144044
+ const mergedVariables = [];
144045
+
144046
+ variables.forEach(variable => {
144047
+ const existingVariable = mergedVariables.find(v =>
144048
+ v.name === variable.name && v.scope === variable.scope
144049
+ );
144050
+
144051
+ if (existingVariable) {
144052
+ merge('origin', existingVariable, variable);
144053
+ merge('provider', existingVariable, variable);
144054
+ mergeEntries(existingVariable, variable);
144055
+ } else {
144056
+ mergedVariables.push(variable);
144057
+ }
144058
+ });
144059
+
144060
+ mapToEditorFormat(mergedVariables);
144061
+
144062
+ parsedVariables[key] = mergedVariables;
144063
+ }
144064
+
144065
+ return parsedVariables;
144066
+ }
144067
+
144068
+ /**
144069
+ * Callback used by `@bpmn-io/extract-process-variables`. It adds additional information from the <AdditionalVariable>
144070
+ * returned from the providers to the <ProcessVariable> that is used by the resolver.
144071
+ *
144072
+ * It does not have a return value, the variables are added as a side effect to the `context.processVariables` array
144073
+ *
144074
+ * @async
144075
+ * @param {Object} context
144076
+ * @param {Array<ModdleElement>} context.elements
144077
+ * @param {ModdleElement} context.containerElement
144078
+ * @param {Array<ProcessVariable>} context.processVariables
144079
+ */
144080
+ async _extractor(context) {
144081
+ const {
144082
+ elements,
144083
+ containerElement,
144084
+ processVariables
144085
+ } = context;
144086
+
144087
+ const self = this;
144088
+
144089
+ const workerTasks = elements.flatMap((element) => {
144090
+ return self.providers.map(async (provider) => {
144091
+ const newVariables = await provider.getVariables(element);
144092
+
144093
+ if (!newVariables) {
144094
+ return;
144095
+ }
144096
+
144097
+ // add scope and origin to variables
144098
+ newVariables.forEach(variable => {
144099
+ processVariables.push({
144100
+ ...cloneVariable(variable),
144101
+ origin: [ element ],
144102
+ scope: variable.scope || getScope(element, containerElement, variable.name),
144103
+ provider: [ provider ]
144104
+ });
144105
+ });
144106
+ });
144107
+ });
144108
+
144109
+ await Promise.all(workerTasks);
144110
+ }
144111
+
144112
+ /**
144113
+ * Add a new VariableProvider. This will be used the next time `getVariables` is called.
144114
+ *
144115
+ * @param {VariableProvider} provider
144116
+ */
144117
+ registerProvider(provider) {
144118
+ this.providers.push(provider);
144119
+ this.invalidateCache();
144120
+ }
144121
+
144122
+ /**
144123
+ * Returns all variables for the given root element.
144124
+ *
144125
+ * @async
144126
+ * @param {ModdleElement} element
144127
+ * @returns {Array<ProcessVariable>} variables
144128
+ */
144129
+ async getProcessVariables(element) {
144130
+ const bo = getBusinessObject$2(element);
144131
+
144132
+ const allVariables = await this.getVariables();
144133
+ return allVariables[bo.id] || [];
144134
+ }
144135
+
144136
+ /**
144137
+ * Returns all variables in the scope of the given element.
144138
+ *
144139
+ * @async
144140
+ * @param {ModdleElement} element
144141
+ * @returns {Array<ProcessVariable>} variables
144142
+ */
144143
+ async getVariablesForElement(element) {
144144
+ const bo = getBusinessObject$2(element);
144145
+
144146
+ const root = getRootElement(bo);
144147
+ const allVariables = await this.getProcessVariables(root);
144148
+
144149
+ // (1) get variables for given scope
144150
+ var scopeVariables = allVariables.filter(function(variable) {
144151
+ return variable.scope.id === bo.id;
144152
+ });
144153
+
144154
+ // (2) get variables for parent scopes
144155
+ var parents = getParents(bo);
144156
+
144157
+ var parentsScopeVariables = allVariables.filter(function(variable) {
144158
+ return parents.find(function(parent) {
144159
+ return parent.id === variable.scope.id;
144160
+ });
144161
+ });
144162
+
144163
+ const reversedVariables = [ ...scopeVariables, ...parentsScopeVariables ].reverse();
144164
+
144165
+ const seenNames = new Set();
144166
+
144167
+ return reversedVariables.filter(variable => {
144168
+
144169
+ // if external variable, keep
144170
+ if (variable.provider.find(extractor => extractor !== this._baseExtractor)) {
144171
+ return true;
144172
+ }
144173
+
144174
+ // if not external, keep only the first occurrence of each name
144175
+ if (!seenNames.has(variable.name)) {
144176
+ seenNames.add(variable.name);
144177
+
144178
+ return true;
144179
+ }
144180
+
144181
+ return false;
144182
+ });
144183
+ }
144184
+ }
144185
+
144186
+ BaseVariableResolver.$inject = [ 'eventBus', 'bpmnjs' ];
144187
+
144188
+
144189
+ // helpers //////////////////////
144190
+
144191
+ function getRootElement(element) {
144192
+ const businessObject = getBusinessObject$2(element);
144193
+
144194
+ if (is$4(businessObject, 'bpmn:Participant')) {
144195
+ return businessObject.processRef;
144196
+ }
144197
+
144198
+ if (is$4(businessObject, 'bpmn:Process')) {
144199
+ return businessObject;
144200
+ }
144201
+
144202
+ let parent = businessObject;
144203
+
144204
+ while (parent.$parent && !is$4(parent, 'bpmn:Process')) {
144205
+ parent = parent.$parent;
144206
+ }
144207
+
144208
+ return parent;
144209
+ }
144210
+
144211
+ function merge(property, target, source) {
144212
+ if (!source[property]) {
144213
+ source[property] = [];
144214
+ }
144215
+
144216
+ if (!target[property]) {
144217
+ target[property] = [];
144218
+ }
144219
+
144220
+ const propertiesToAdd = source[property].filter(o => !target[property].includes(o));
144221
+
144222
+ target[property].push(...propertiesToAdd);
144223
+ }
144224
+
144225
+ function mergeEntries(target, source, visited = []) {
144226
+ if (visited.includes(source) || visited.includes(target)) {
144227
+ return;
144228
+ }
144229
+ visited.push(source);
144230
+ visited.push(target);
144231
+
144232
+ target.type = extendList(target.type, source.type, '|');
144233
+ target.info = extendList(target.info, source.info, '\n');
144234
+ target.isList = !!target.isList === !!source.isList ? target.isList : 'optional';
144235
+
144236
+ if (!source.entries) {
144237
+ return;
144238
+ }
144239
+
144240
+ if (!target.entries) {
144241
+ target.entries = [];
144242
+ }
144243
+
144244
+ source.entries.forEach(variable => {
144245
+ const existingEntry = target.entries.find(e => e.name === variable.name);
144246
+
144247
+ if (existingEntry) {
144248
+ mergeEntries(existingEntry, variable, visited);
144249
+ } else {
144250
+ target.entries.push(variable);
144251
+ }
144252
+ });
144253
+ }
144254
+
144255
+ const extendList = (target, source, separator) => {
144256
+ if (!target || target === source) {
144257
+ return source;
144258
+ } else {
144259
+ const existingTypes = target.split(separator);
144260
+ if (!existingTypes.includes(source)) {
144261
+ existingTypes.push(source);
144262
+ }
144263
+ return existingTypes.join(separator);
144264
+ }
144265
+ };
144266
+
144267
+ function mapToEditorFormat(variables) {
144268
+ if (!variables) {
144269
+ return;
144270
+ }
144271
+
144272
+ variables.forEach(variable => {
144273
+ variable.detail = variable.type;
144274
+ mapToEditorFormat(variable.entries);
144275
+ });
144276
+ }
144277
+
144278
+ function cloneVariable(variable) {
144279
+ const newVariable = { ...variable };
144280
+
144281
+ if (newVariable.entries) {
144282
+ newVariable.entries = newVariable.entries.map(cloneVariable);
144283
+ }
144284
+
144285
+ return newVariable;
144286
+ }
144287
+
144288
+ class EntriesContext extends VariableContext$1 {
144289
+ constructor(value = { entries: {} }) {
144290
+ super(value);
144291
+
144292
+ this.value.entries = this.value.entries || {};
144293
+
144294
+ const context = this.value;
144295
+
144296
+ for (const key in context.entries) {
144297
+ const entry = context.entries[key];
144298
+
144299
+ if (entry instanceof EntriesContext) {
144300
+ continue;
144301
+ }
144302
+
144303
+ context.entries[key] = this.constructor.of(context.entries[key]);
144304
+ }
144305
+ }
144306
+
144307
+ getKeys() {
144308
+ return Object.keys(this.value.entries);
144309
+ }
144310
+
144311
+ get(key) {
144312
+ const value = this.value.entries[key];
144313
+
144314
+ if (!value) {
144315
+ return value;
144316
+ }
144317
+
144318
+ if (value.atomic) {
144319
+ return value.atomicValue;
144320
+ }
144321
+
144322
+ return value;
144323
+ }
144324
+
144325
+ set(key, value) {
144326
+ return this.constructor.of(
144327
+ {
144328
+ ...this.value,
144329
+ entries: {
144330
+ ...this.value.entries,
144331
+ [key]: value
144332
+ }
144333
+ }
144334
+ );
144335
+ }
144336
+
144337
+ static of(...contexts) {
144338
+ const unwrap = (context) => {
144339
+
144340
+ if (
144341
+ this.isAtomic(context)
144342
+ ) {
144343
+ if (context instanceof this) {
144344
+ return context.value;
144345
+ }
144346
+
144347
+ return {
144348
+ atomic: true,
144349
+ atomicValue: context
144350
+ };
144351
+ }
144352
+
144353
+ return { ...context };
144354
+ };
144355
+
144356
+ const merged = contexts.reduce((merged, context) => {
144357
+
144358
+ const {
144359
+ entries = {},
144360
+ ...rest
144361
+ } = unwrap(context);
144362
+
144363
+ return {
144364
+ ...merged,
144365
+ ...rest,
144366
+ entries: {
144367
+ ...merged.entries,
144368
+ ...entries
144369
+ }
144370
+ };
144371
+ }, {});
144372
+
144373
+ return new this(merged);
144374
+ }
144375
+ }
144376
+
144377
+ function parseVariables(variables) {
144378
+
144379
+ const variablesToResolve = [];
144380
+
144381
+ // Step 1 - Parse all variables and populate all that don't have references
144382
+ // to other variables
144383
+ variables.forEach(variable => {
144384
+ variable.origin.forEach(origin => {
144385
+ const expressionDetails = getExpressionDetails(variable, origin);
144386
+
144387
+ if (!expressionDetails) {
144388
+ return;
144389
+ }
144390
+
144391
+ const { expression, unresolved } = expressionDetails;
144392
+
144393
+ variablesToResolve.push({ variable, expression, unresolved });
144394
+ });
144395
+ });
144396
+
144397
+ // Step 2 - Order all Variables and resolve them
144398
+ return resolveReferences(variablesToResolve, variables);
144399
+ }
144400
+
144401
+ function resolveReferences(variablesToResolve, allVariables) {
144402
+ const sortedVariables = [];
144403
+
144404
+ // Step 2.1 - Try to order Variables that rely on each other
144405
+ variablesToResolve.forEach((details) => {
144406
+ const { variable, unresolved } = details;
144407
+ const insertBefore = sortedVariables.findIndex(({ unresolved: u }) => {
144408
+ return u.includes(variable.name);
144409
+ });
144410
+
144411
+ // Insert directly before the first variable that depends on this one
144412
+ if (insertBefore > -1) {
144413
+ sortedVariables.splice(insertBefore, 0, details);
144414
+ return;
144415
+ }
144416
+
144417
+ // Insert directly after the last variable that this one depends on
144418
+ // this ensures that later downstream variables are behind this one
144419
+ const insertAfter = sortedVariables.findLastIndex(({ variable: v }) => {
144420
+ return unresolved.includes(v.name);
144421
+ });
144422
+
144423
+ if (insertAfter > -1) {
144424
+ sortedVariables.splice(insertAfter + 1, 0, details);
144425
+ return;
144426
+ }
144427
+
144428
+ sortedVariables.push(details);
144429
+ });
144430
+
144431
+ const variablesWithoutMappings = allVariables.filter(v =>
144432
+ !variablesToResolve.find(({ variable: unresolved }) => {
144433
+ })
144434
+ );
144435
+
144436
+ const rootContext = {
144437
+ entries: toOptimizedFormat(variablesWithoutMappings)
144438
+ };
144439
+
144440
+ const newVariables = [];
144441
+
144442
+ // Step 2.2 - parse in order, building up the context with resolved variable values
144443
+ // This will resolve all variables that don't have circular dependencies on each other
144444
+ sortedVariables.forEach(({ variable, expression }) => {
144445
+ const resultContext = getResultContext(expression, filterForScope(rootContext, variable));
144446
+
144447
+ let computedResult = resultContext.computedValue();
144448
+
144449
+ // Wrap primitive values in an EntriesContext
144450
+ if (!(computedResult instanceof EntriesContext)) {
144451
+ computedResult = EntriesContext.of(computedResult);
144452
+ }
144453
+
144454
+ // Ensure we don't copy the scope from the mapped variable
144455
+ computedResult.scope = variable.scope;
144456
+
144457
+ rootContext.entries[variable.name] = computedResult;
144458
+
144459
+ newVariables.push({
144460
+ newVariable: toUnifiedFormat({
144461
+ [variable.name]: computedResult
144462
+ })[0],
144463
+ oldVariable: variable
144464
+ });
144465
+ });
144466
+
144467
+ // Ensure meta-data (scope, origin) is kept from original variable
144468
+ const result = newVariables.map(({ newVariable, oldVariable }) => {
144469
+ if (oldVariable) {
144470
+ return {
144471
+ ...newVariable,
144472
+ ...oldVariable
144473
+ };
144474
+ }
144475
+ return newVariable;
144476
+ });
144477
+
144478
+ return result;
144479
+ }
144480
+
144481
+
144482
+ // helpers //////////////////////
144483
+
144484
+ /**
144485
+ * Parses the expression with the given variables and return the result context
144486
+ *
144487
+ * @param {String} expression
144488
+ * @param {Variables} variables
144489
+ * @returns {EntriesContext}
144490
+ */
144491
+ function getResultContext(expression, variables = {}) {
144492
+ const contextTracker = trackVariables$1(variables, EntriesContext);
144493
+
144494
+ // This is a hack to get the latest variables from the context tracker
144495
+ // lezer does not automatically annotate the parse tree with the context
144496
+ let latestVariables = contextTracker.start;
144497
+
144498
+ const customContextTracker = new ContextTracker({
144499
+ start: contextTracker.start,
144500
+ reduce(...args) {
144501
+ const result = contextTracker.reduce(...args);
144502
+ latestVariables = result;
144503
+ return result;
144504
+ }
144505
+ });
144506
+
144507
+ const contextualParser = parser$3.configure({
144508
+ contextTracker: customContextTracker,
144509
+ strict: true
144510
+ });
144511
+
144512
+ try {
144513
+ contextualParser.parse(expression);
144514
+ } catch (error) {
144515
+
144516
+ // bail out in case of an error
144517
+ return latestVariables;
144518
+ }
144519
+
144520
+ return latestVariables;
144375
144521
  }
144376
144522
 
144377
- function parseVariables(variables) {
144378
-
144379
- const variablesToResolve = [];
144380
-
144381
- // Step 1 - Parse all variables and populate all that don't have references
144382
- // to other variables
144383
- variables.forEach(variable => {
144384
- variable.origin.forEach(origin => {
144385
- const expressionDetails = getExpressionDetails(variable, origin);
144386
-
144387
- if (!expressionDetails) {
144388
- return;
144389
- }
144390
-
144391
- const { expression, unresolved } = expressionDetails;
144392
-
144393
- variablesToResolve.push({ variable, expression, unresolved });
144394
- });
144395
- });
144396
-
144397
- // Step 2 - Order all Variables and resolve them
144398
- return resolveReferences(variablesToResolve, variables);
144399
- }
144400
-
144401
- function resolveReferences(variablesToResolve, allVariables) {
144402
- const sortedVariables = [];
144403
-
144404
- // Step 2.1 - Try to order Variables that rely on each other
144405
- variablesToResolve.forEach((details) => {
144406
- const { variable, unresolved } = details;
144407
- const insertBefore = sortedVariables.findIndex(({ unresolved: u }) => {
144408
- return u.includes(variable.name);
144409
- });
144410
-
144411
- // Insert directly before the first variable that depends on this one
144412
- if (insertBefore > -1) {
144413
- sortedVariables.splice(insertBefore, 0, details);
144414
- return;
144415
- }
144416
-
144417
- // Insert directly after the last variable that this one depends on
144418
- // this ensures that later downstream variables are behind this one
144419
- const insertAfter = sortedVariables.findLastIndex(({ variable: v }) => {
144420
- return unresolved.includes(v.name);
144421
- });
144422
-
144423
- if (insertAfter > -1) {
144424
- sortedVariables.splice(insertAfter + 1, 0, details);
144425
- return;
144426
- }
144427
-
144428
- sortedVariables.push(details);
144429
- });
144430
-
144431
- const variablesWithoutMappings = allVariables.filter(v =>
144432
- !variablesToResolve.find(({ variable: unresolved }) => {
144433
- })
144434
- );
144435
-
144436
- const rootContext = {
144437
- entries: toOptimizedFormat(variablesWithoutMappings)
144438
- };
144439
-
144440
- const newVariables = [];
144441
-
144442
- // Step 2.2 - parse in order, building up the context with resolved variable values
144443
- // This will resolve all variables that don't have circular dependencies on each other
144444
- sortedVariables.forEach(({ variable, expression }) => {
144445
- const resultContext = getResultContext(expression, filterForScope(rootContext, variable));
144446
-
144447
- let computedResult = resultContext.computedValue();
144448
-
144449
- // Wrap primitive values in an EntriesContext
144450
- if (!(computedResult instanceof EntriesContext)) {
144451
- computedResult = EntriesContext.of(computedResult);
144452
- }
144453
-
144454
- // Ensure we don't copy the scope from the mapped variable
144455
- computedResult.scope = variable.scope;
144456
-
144457
- rootContext.entries[variable.name] = computedResult;
144458
-
144459
- newVariables.push({
144460
- newVariable: toUnifiedFormat({
144461
- [variable.name]: computedResult
144462
- })[0],
144463
- oldVariable: variable
144464
- });
144465
- });
144466
-
144467
- // Ensure meta-data (scope, origin) is kept from original variable
144468
- const result = newVariables.map(({ newVariable, oldVariable }) => {
144469
- if (oldVariable) {
144470
- return {
144471
- ...newVariable,
144472
- ...oldVariable
144473
- };
144474
- }
144475
- return newVariable;
144476
- });
144477
-
144478
- return result;
144479
- }
144480
-
144481
-
144482
- // helpers //////////////////////
144483
-
144484
- /**
144485
- * Parses the expression with the given variables and return the result context
144486
- *
144487
- * @param {String} expression
144488
- * @param {Variables} variables
144489
- * @returns {EntriesContext}
144490
- */
144491
- function getResultContext(expression, variables = {}) {
144492
- const contextTracker = trackVariables$1(variables, EntriesContext);
144493
-
144494
- // This is a hack to get the latest variables from the context tracker
144495
- // lezer does not automatically annotate the parse tree with the context
144496
- let latestVariables = null;
144497
-
144498
- const customContextTracker = new ContextTracker({
144499
- start: contextTracker.start,
144500
- reduce(...args) {
144501
- const result = contextTracker.reduce(...args);
144502
- latestVariables = result;
144503
- return result;
144504
- }
144505
- });
144506
-
144507
- const contextualParser = parser$3.configure({
144508
- contextTracker: customContextTracker
144509
- });
144510
-
144511
- contextualParser.parse(expression);
144512
-
144513
- return latestVariables;
144514
- }
144515
-
144516
- /**
144517
- * Given a Variable and a specific origin, return the mapping expression and all
144518
- * unresolved variables used in that expression. Returns undefined if no mapping
144519
- * exists for the given origin.
144520
- *
144521
- * @param {ProcessVariable} variable
144522
- * @param {djs.model.Base} origin
144523
- * @returns {{ expression: String, unresolved: Array<String> }}}
144524
- */
144525
- function getExpressionDetails(variable, origin) {
144526
-
144527
- // if variable scope is !== origin (global), prioritize IoExpression over ScriptExpression
144528
- // if variable scope is === origin (local), prioritize ScriptExpression over IoExpression
144529
- const expression = variable.scope !== origin
144530
- ? getIoExpression(variable, origin) || getScriptExpression(variable, origin)
144531
- : getScriptExpression(variable, origin) || getIoExpression(variable, origin);
144532
-
144533
- if (!expression) {
144534
- return;
144535
- }
144536
-
144537
- const result = getResultContext(expression);
144538
-
144539
- const unresolved = findUnresolvedVariables(result);
144540
-
144541
- return { expression, unresolved };
144542
- }
144543
-
144544
- /**
144545
- * Given a Variable and a specific origin, return the mapping expression for all
144546
- * input outputs mapping. Returns undefined if no mapping exists for the given origin.
144547
- *
144548
- * @param {ProcessVariable} variable
144549
- * @param {djs.model.Base} origin
144550
- * @returns { expression: String}
144551
- */
144552
- function getIoExpression(variable, origin) {
144553
- const ioMapping = getExtensionElementsList(origin, 'zeebe:IoMapping')[0];
144554
-
144555
- if (!ioMapping) {
144556
- return;
144557
- }
144558
-
144559
- let mappings;
144560
- if (origin === variable.scope) {
144561
- mappings = ioMapping.inputParameters;
144562
- } else {
144563
- mappings = ioMapping.outputParameters;
144564
- }
144565
-
144566
- if (!mappings) {
144567
- return;
144568
- }
144569
-
144570
- const mapping = mappings.slice().reverse().find(mapping => mapping.target === variable.name);
144571
-
144572
- if (!mapping || !mapping.source) {
144573
- return;
144574
- }
144575
-
144576
- return mapping.source.substring(1);
144577
-
144578
- }
144579
-
144580
- /**
144581
- * Given a Variable and a specific origin, return the mapping expression for script
144582
- * task result variable. Returns undefined if no mapping exists for the given origin.
144583
- *
144584
- * @param {ProcessVariable} variable
144585
- * @param {djs.model.Base} origin
144586
- * @returns {string}
144587
- */
144588
- function getScriptExpression(variable, origin) {
144589
- const script = getExtensionElementsList(origin, 'zeebe:Script')[0];
144590
-
144591
- if (!script || !script.expression) {
144592
- return;
144593
- }
144594
-
144595
- if (script.resultVariable === variable.name) {
144596
- return script.expression.substring(1);
144597
- }
144598
- }
144599
-
144600
- /**
144601
- * Traverses the parseTree and returns all `VariableName` nodes with no value
144602
- *
144603
- * @param {Object} node
144604
- * @returns {Array<String>}
144605
- */
144606
- function findUnresolvedVariables(node) {
144607
- const results = [];
144608
-
144609
- results.push(...(node.children.flatMap(findUnresolvedVariables)));
144610
-
144611
- if (node.name === 'VariableName' && !node.value) {
144612
- results.push(node.raw);
144613
- }
144614
-
144615
- return results;
144616
- }
144617
-
144618
-
144619
- /**
144620
- * Transforms the entries of a variable from an array to an object.
144621
- * This allows faster lookup times during parsing.
144622
- *
144623
- * [ { name, entries: [] } ]
144624
- * to
144625
- * {name: { name, entries: {} }}
144626
- */
144627
- function toOptimizedFormat(variables) {
144628
-
144629
- if (!variables) {
144630
- return;
144631
- }
144632
-
144633
- const result = {};
144634
-
144635
- variables.forEach(variable => {
144636
- result[variable.name] = { ...variable };
144637
- result[variable.name].entries = toOptimizedFormat(variable.entries);
144638
- });
144639
-
144640
- return result;
144641
- }
144642
-
144643
- /**
144644
- * Transforms EntriesContext to the format required by the feel-editor
144645
- */
144646
- function toUnifiedFormat(variables) {
144647
- if (!variables) {
144648
- return;
144649
- }
144650
-
144651
- const result = [];
144652
-
144653
- for (const key in variables) {
144654
- let variable = variables[key];
144655
-
144656
- if (variable instanceof EntriesContext) {
144657
- variable = variable.value;
144658
- }
144659
-
144660
- if (!variable) {
144661
- result.push({
144662
- name: key
144663
- });
144664
- continue;
144665
- }
144666
-
144667
- result.push({
144668
- ...annotate(variable),
144669
- entries: toUnifiedFormat(variable.entries),
144670
- name: key,
144671
- scope: variable.scope
144672
- });
144673
- }
144674
-
144675
- return result;
144676
- }
144677
-
144678
-
144679
- function annotate(variable) {
144680
- return {
144681
- ...variable,
144682
- type: getType$1(variable),
144683
- info: getInfo(variable)
144684
- };
144685
-
144686
- }
144687
-
144688
- function getType$1(variable) {
144689
-
144690
- if (!variable) {
144691
- return '';
144692
- }
144693
-
144694
- if (variable.type) {
144695
- return variable.type;
144696
- }
144697
-
144698
- if (variable.entries && Object.keys(variable.entries).length) {
144699
- return 'Context';
144700
- }
144701
-
144702
- if (variable.atomicValue) {
144703
- return capitalize$1(typeof variable.atomicValue);
144704
- }
144705
-
144706
- return '';
144707
- }
144708
-
144709
- function getInfo(variable) {
144710
- if (!variable) {
144711
- return '';
144712
- }
144713
-
144714
- if (variable.info) {
144715
- return variable.info;
144716
- }
144717
-
144718
- if (variable.atomicValue) {
144719
- return '' + variable.atomicValue;
144720
- }
144721
-
144722
- return '';
144723
- }
144724
-
144725
- function capitalize$1(string) {
144726
- return string.charAt(0).toUpperCase() + string.slice(1);
144727
- }
144728
-
144729
- function filterForScope(context, variable) {
144730
- const scopedResults = {
144731
- entries: {}
144732
- };
144733
-
144734
- const validScopes = variable.origin.flatMap(bo => {
144735
- return [ bo, ...getParents(bo) ];
144736
- });
144737
-
144738
- for (const key in context.entries) {
144739
- const entry = context.entries[key];
144740
-
144741
- if (validScopes.find(scope => scope.id === entry.scope.id)) {
144742
- scopedResults.entries[key] = entry;
144743
- }
144744
- }
144745
-
144746
- return scopedResults;
144747
- }
144748
-
144749
- /**
144750
- * Remove input/output element name after current definition
144751
- */
144752
- function getElementNamesToRemove(moddleElement, inputOutput) {
144753
- const namesToFilter = [];
144754
-
144755
- // Input: remove all inputs defined after the current input definition
144756
- if (is$4(moddleElement, 'zeebe:Input')) {
144757
- const allInputs = inputOutput.inputParameters;
144758
-
144759
- const inputsToFilter =
144760
- allInputs
144761
- .slice(allInputs.indexOf(moddleElement))
144762
- .map(o => o.target);
144763
-
144764
- namesToFilter.push(...inputsToFilter);
144765
- }
144766
-
144767
- const allOutputs = inputOutput.outputParameters;
144768
-
144769
- // Output: remove all outputs defined after the current output definition
144770
- if (is$4(moddleElement, 'zeebe:Output')) {
144771
-
144772
- // Get all output mappings defined after the current element, including own name
144773
- const outputsToFilter = allOutputs
144774
- .slice(allOutputs.indexOf(moddleElement))
144775
- .map(o => o.target);
144776
-
144777
- namesToFilter.push(...outputsToFilter);
144778
- }
144779
-
144780
- // Input or general property: remove all outputs
144781
- else if (allOutputs) {
144782
-
144783
- // Input or execution-related element, remove all outputs
144784
- const outputsToFilter = allOutputs
144785
- .map(o => o.target);
144786
-
144787
- namesToFilter.push(...outputsToFilter);
144788
- }
144789
-
144790
- return namesToFilter;
144523
+ /**
144524
+ * Given a Variable and a specific origin, return the mapping expression and all
144525
+ * unresolved variables used in that expression. Returns undefined if no mapping
144526
+ * exists for the given origin.
144527
+ *
144528
+ * @param {ProcessVariable} variable
144529
+ * @param {djs.model.Base} origin
144530
+ * @returns {{ expression: String, unresolved: Array<String> }}}
144531
+ */
144532
+ function getExpressionDetails(variable, origin) {
144533
+
144534
+ // if variable scope is !== origin (global), prioritize IoExpression over ScriptExpression
144535
+ // if variable scope is === origin (local), prioritize ScriptExpression over IoExpression
144536
+ const expression = variable.scope !== origin
144537
+ ? getIoExpression(variable, origin) || getScriptExpression(variable, origin)
144538
+ : getScriptExpression(variable, origin) || getIoExpression(variable, origin);
144539
+
144540
+ if (!expression) {
144541
+ return;
144542
+ }
144543
+
144544
+ const result = getResultContext(expression);
144545
+
144546
+ const unresolved = findUnresolvedVariables(result);
144547
+
144548
+ return { expression, unresolved };
144549
+ }
144550
+
144551
+ /**
144552
+ * Given a Variable and a specific origin, return the mapping expression for all
144553
+ * input outputs mapping. Returns undefined if no mapping exists for the given origin.
144554
+ *
144555
+ * @param {ProcessVariable} variable
144556
+ * @param {djs.model.Base} origin
144557
+ * @returns { expression: String}
144558
+ */
144559
+ function getIoExpression(variable, origin) {
144560
+ const ioMapping = getExtensionElementsList(origin, 'zeebe:IoMapping')[0];
144561
+
144562
+ if (!ioMapping) {
144563
+ return;
144564
+ }
144565
+
144566
+ let mappings;
144567
+ if (origin === variable.scope) {
144568
+ mappings = ioMapping.inputParameters;
144569
+ } else {
144570
+ mappings = ioMapping.outputParameters;
144571
+ }
144572
+
144573
+ if (!mappings) {
144574
+ return;
144575
+ }
144576
+
144577
+ const mapping = mappings.slice().reverse().find(mapping => mapping.target === variable.name);
144578
+
144579
+ if (!mapping || !mapping.source) {
144580
+ return;
144581
+ }
144582
+
144583
+ return mapping.source.substring(1);
144584
+
144585
+ }
144586
+
144587
+ /**
144588
+ * Given a Variable and a specific origin, return the mapping expression for script
144589
+ * task result variable. Returns undefined if no mapping exists for the given origin.
144590
+ *
144591
+ * @param {ProcessVariable} variable
144592
+ * @param {djs.model.Base} origin
144593
+ * @returns {string}
144594
+ */
144595
+ function getScriptExpression(variable, origin) {
144596
+ const script = getExtensionElementsList(origin, 'zeebe:Script')[0];
144597
+
144598
+ if (!script || !script.expression) {
144599
+ return;
144600
+ }
144601
+
144602
+ if (script.resultVariable === variable.name) {
144603
+ return script.expression.substring(1);
144604
+ }
144605
+ }
144606
+
144607
+ /**
144608
+ * Traverses the parseTree and returns all `VariableName` nodes with no value
144609
+ *
144610
+ * @param {Object} node
144611
+ * @returns {Array<String>}
144612
+ */
144613
+ function findUnresolvedVariables(node) {
144614
+ const results = [];
144615
+
144616
+ results.push(...(node.children.flatMap(findUnresolvedVariables)));
144617
+
144618
+ if (node.name === 'VariableName' && !node.value) {
144619
+ results.push(node.raw);
144620
+ }
144621
+
144622
+ return results;
144623
+ }
144624
+
144625
+
144626
+ /**
144627
+ * Transforms the entries of a variable from an array to an object.
144628
+ * This allows faster lookup times during parsing.
144629
+ *
144630
+ * [ { name, entries: [] } ]
144631
+ * to
144632
+ * {name: { name, entries: {} }}
144633
+ */
144634
+ function toOptimizedFormat(variables) {
144635
+
144636
+ if (!variables) {
144637
+ return;
144638
+ }
144639
+
144640
+ const result = {};
144641
+
144642
+ variables.forEach(variable => {
144643
+ result[variable.name] = { ...variable };
144644
+ result[variable.name].entries = toOptimizedFormat(variable.entries);
144645
+ });
144646
+
144647
+ return result;
144791
144648
  }
144792
144649
 
144793
- const HIGH_PRIORITY$1 = 2000;
144794
-
144795
- /**
144796
- * The Camunda 8 Implementation for the VariableResolver.
144797
- */
144798
- class ZeebeVariableResolver extends BaseVariableResolver {
144799
- constructor(eventBus, bpmnjs) {
144800
- super(eventBus, bpmnjs);
144801
- this._baseExtractor = getProcessVariables;
144802
-
144803
- eventBus.on('variableResolver.parseVariables', HIGH_PRIORITY$1, this._resolveVariables);
144804
- }
144805
-
144806
- async getVariablesForElement(element, moddleElement) {
144807
- const variables = await super.getVariablesForElement(element);
144808
-
144809
- const bo = getBusinessObject$2(element);
144810
-
144811
- if (!moddleElement) {
144812
- return variables;
144813
- }
144814
-
144815
- const inputOutput = getInputOutput(bo);
144816
-
144817
- if (!inputOutput) {
144818
- return variables;
144819
- }
144820
-
144821
- const namesToFilter = getElementNamesToRemove(moddleElement, inputOutput);
144822
-
144823
- return variables.filter(v => {
144824
-
144825
- // Keep all variables that are also defined in other elements
144826
- if (v.origin.length > 1 || v.origin[0] !== bo) {
144827
- return true;
144828
- }
144829
-
144830
- // Keep all variables from external data providers in outputs
144831
- if (
144832
- is$4(moddleElement, 'zeebe:Output') &&
144833
- v.provider.find(extractor => extractor !== this._baseExtractor)
144834
- ) {
144835
- return true;
144836
- }
144837
-
144838
- // Filter all pre-defined variables
144839
- return !namesToFilter.includes(v.name);
144840
- });
144841
- }
144842
-
144843
- /**
144844
- * Parsed the variables and resolves the variable schema to kept the
144845
- * variable schema throughout the process.
144846
- *
144847
- * @param {Event} e
144848
- * @param {Object} context
144849
- * @param {Array<ProcessVariable>} context.variables
144850
- */
144851
- _resolveVariables(e, context) {
144852
- const rawVariables = context.variables;
144853
-
144854
- const mappedVariables = {};
144855
-
144856
- for (const key in rawVariables) {
144857
- const variables = rawVariables[key];
144858
- const newVariables = parseVariables(variables);
144859
-
144860
- mappedVariables[key] = [ ...variables, ...newVariables ];
144861
- }
144862
-
144863
- context.variables = mappedVariables;
144864
- }
144650
+ /**
144651
+ * Transforms EntriesContext to the format required by the feel-editor
144652
+ */
144653
+ function toUnifiedFormat(variables) {
144654
+ if (!variables) {
144655
+ return;
144656
+ }
144657
+
144658
+ const result = [];
144659
+
144660
+ for (const key in variables) {
144661
+ let variable = variables[key];
144662
+
144663
+ if (variable instanceof EntriesContext) {
144664
+ variable = variable.value;
144665
+ }
144666
+
144667
+ if (!variable) {
144668
+ result.push({
144669
+ name: key
144670
+ });
144671
+ continue;
144672
+ }
144673
+
144674
+ result.push({
144675
+ ...annotate(variable),
144676
+ entries: toUnifiedFormat(variable.entries),
144677
+ name: key,
144678
+ scope: variable.scope
144679
+ });
144680
+ }
144681
+
144682
+ return result;
144683
+ }
144684
+
144685
+
144686
+ function annotate(variable) {
144687
+ return {
144688
+ ...variable,
144689
+ type: getType$1(variable),
144690
+ info: getInfo(variable)
144691
+ };
144692
+
144693
+ }
144694
+
144695
+ function getType$1(variable) {
144696
+
144697
+ if (!variable) {
144698
+ return '';
144699
+ }
144700
+
144701
+ if (variable.type) {
144702
+ return variable.type;
144703
+ }
144704
+
144705
+ if (variable.entries && Object.keys(variable.entries).length) {
144706
+ return 'Context';
144707
+ }
144708
+
144709
+ if (variable.atomicValue) {
144710
+ return capitalize$1(typeof variable.atomicValue);
144711
+ }
144712
+
144713
+ return '';
144714
+ }
144715
+
144716
+ function getInfo(variable) {
144717
+ if (!variable) {
144718
+ return '';
144719
+ }
144720
+
144721
+ if (variable.info) {
144722
+ return variable.info;
144723
+ }
144724
+
144725
+ if (variable.atomicValue) {
144726
+ return '' + variable.atomicValue;
144727
+ }
144728
+
144729
+ return '';
144730
+ }
144731
+
144732
+ function capitalize$1(string) {
144733
+ return string.charAt(0).toUpperCase() + string.slice(1);
144734
+ }
144735
+
144736
+ function filterForScope(context, variable) {
144737
+ const scopedResults = {
144738
+ entries: {}
144739
+ };
144740
+
144741
+ const validScopes = variable.origin.flatMap(bo => {
144742
+ return [ bo, ...getParents(bo) ];
144743
+ });
144744
+
144745
+ for (const key in context.entries) {
144746
+ const entry = context.entries[key];
144747
+
144748
+ if (validScopes.find(scope => scope.id === entry.scope.id)) {
144749
+ scopedResults.entries[key] = entry;
144750
+ }
144751
+ }
144752
+
144753
+ return scopedResults;
144754
+ }
144755
+
144756
+ /**
144757
+ * Remove input/output element name after current definition
144758
+ */
144759
+ function getElementNamesToRemove(moddleElement, inputOutput) {
144760
+ const namesToFilter = [];
144761
+
144762
+ // Input: remove all inputs defined after the current input definition
144763
+ if (is$4(moddleElement, 'zeebe:Input')) {
144764
+ const allInputs = inputOutput.inputParameters;
144765
+
144766
+ const inputsToFilter =
144767
+ allInputs
144768
+ .slice(allInputs.indexOf(moddleElement))
144769
+ .map(o => o.target);
144770
+
144771
+ namesToFilter.push(...inputsToFilter);
144772
+ }
144773
+
144774
+ const allOutputs = inputOutput.outputParameters;
144775
+
144776
+ // Output: remove all outputs defined after the current output definition
144777
+ if (is$4(moddleElement, 'zeebe:Output')) {
144778
+
144779
+ // Get all output mappings defined after the current element, including own name
144780
+ const outputsToFilter = allOutputs
144781
+ .slice(allOutputs.indexOf(moddleElement))
144782
+ .map(o => o.target);
144783
+
144784
+ namesToFilter.push(...outputsToFilter);
144785
+ }
144786
+
144787
+ // Input or general property: remove all outputs
144788
+ else if (allOutputs) {
144789
+
144790
+ // Input or execution-related element, remove all outputs
144791
+ const outputsToFilter = allOutputs
144792
+ .map(o => o.target);
144793
+
144794
+ namesToFilter.push(...outputsToFilter);
144795
+ }
144796
+
144797
+ return namesToFilter;
144798
+ }
144799
+
144800
+ const HIGH_PRIORITY$1 = 2000;
144801
+
144802
+ /**
144803
+ * The Camunda 8 Implementation for the VariableResolver.
144804
+ */
144805
+ class ZeebeVariableResolver extends BaseVariableResolver {
144806
+ constructor(eventBus, bpmnjs) {
144807
+ super(eventBus, bpmnjs);
144808
+ this._baseExtractor = getProcessVariables;
144809
+
144810
+ eventBus.on('variableResolver.parseVariables', HIGH_PRIORITY$1, this._resolveVariables);
144811
+ }
144812
+
144813
+ async getVariablesForElement(element, moddleElement) {
144814
+ const variables = await super.getVariablesForElement(element);
144815
+
144816
+ const bo = getBusinessObject$2(element);
144817
+
144818
+ if (!moddleElement) {
144819
+ return variables;
144820
+ }
144821
+
144822
+ const inputOutput = getInputOutput(bo);
144823
+
144824
+ if (!inputOutput) {
144825
+ return variables;
144826
+ }
144827
+
144828
+ const namesToFilter = getElementNamesToRemove(moddleElement, inputOutput);
144829
+
144830
+ return variables.filter(v => {
144831
+
144832
+ // Keep all variables that are also defined in other elements
144833
+ if (v.origin.length > 1 || v.origin[0] !== bo) {
144834
+ return true;
144835
+ }
144836
+
144837
+ // Keep all variables from external data providers in outputs
144838
+ if (
144839
+ is$4(moddleElement, 'zeebe:Output') &&
144840
+ v.provider.find(extractor => extractor !== this._baseExtractor)
144841
+ ) {
144842
+ return true;
144843
+ }
144844
+
144845
+ // Filter all pre-defined variables
144846
+ return !namesToFilter.includes(v.name);
144847
+ });
144848
+ }
144849
+
144850
+ /**
144851
+ * Parsed the variables and resolves the variable schema to kept the
144852
+ * variable schema throughout the process.
144853
+ *
144854
+ * @param {Event} e
144855
+ * @param {Object} context
144856
+ * @param {Array<ProcessVariable>} context.variables
144857
+ */
144858
+ _resolveVariables(e, context) {
144859
+ const rawVariables = context.variables;
144860
+
144861
+ const mappedVariables = {};
144862
+
144863
+ for (const key in rawVariables) {
144864
+ const variables = rawVariables[key];
144865
+ const newVariables = parseVariables(variables);
144866
+
144867
+ mappedVariables[key] = [ ...variables, ...newVariables ];
144868
+ }
144869
+
144870
+ context.variables = mappedVariables;
144871
+ }
144872
+ }
144873
+
144874
+ /**
144875
+ * @typedef Variable
144876
+ * @property {string} name The name of the variable
144877
+ * @property {string} [type] The type of the variable
144878
+ * @property {string} [info] A description of the variable displayed as a tooltip
144879
+ * @property {boolean} [isList] whether the variable is a list
144880
+ * @property {Array<Variable>} [entries] If the variable is a context, this contains the entries of the context
144881
+ * @property {djs.model.Base} [scope] The scope of the variable, by default it is the container element of the element the variable is created from
144882
+ */
144883
+
144884
+ /**
144885
+ * A basic provider that may be extended to provide variables for the variable resolver.
144886
+ *
144887
+ * Extensions should implement the method `getVariables`.
144888
+ */
144889
+ class VariableProvider {
144890
+ constructor(variableResolver) {
144891
+ this._variableResolver = variableResolver;
144892
+ this.register();
144893
+ }
144894
+
144895
+ /**
144896
+ * This method should implement the creation of a list of process variables.
144897
+ *
144898
+ * @param {djs.model.Base} element
144899
+ * @return {Array<Variable>} a list of process variables
144900
+ *
144901
+ * The following example contains one variable
144902
+ *
144903
+ * @example
144904
+ * VariableProvider.getVariables = function(element) {
144905
+ * const variables = [
144906
+ * {
144907
+ * name: 'myVariable',
144908
+ * type: 'String',
144909
+ * info: 'This is a global variable'
144910
+ * }
144911
+ * ];
144912
+ *
144913
+ * if (is(element, 'bpmn:Process')) {
144914
+ * return variables;
144915
+ * }
144916
+ * }
144917
+ */
144918
+ getVariables(element) { }
144919
+
144920
+ register() {
144921
+ this._variableResolver.registerProvider(this);
144922
+ }
144865
144923
  }
144866
144924
 
144867
- /**
144868
- * @typedef Variable
144869
- * @property {string} name The name of the variable
144870
- * @property {string} [type] The type of the variable
144871
- * @property {string} [info] A description of the variable displayed as a tooltip
144872
- * @property {boolean} [isList] whether the variable is a list
144873
- * @property {Array<Variable>} [entries] If the variable is a context, this contains the entries of the context
144874
- * @property {djs.model.Base} [scope] The scope of the variable, by default it is the container element of the element the variable is created from
144875
- */
144876
-
144877
- /**
144878
- * A basic provider that may be extended to provide variables for the variable resolver.
144879
- *
144880
- * Extensions should implement the method `getVariables`.
144881
- */
144882
- class VariableProvider {
144883
- constructor(variableResolver) {
144884
- this._variableResolver = variableResolver;
144885
- this.register();
144886
- }
144887
-
144888
- /**
144889
- * This method should implement the creation of a list of process variables.
144890
- *
144891
- * @param {djs.model.Base} element
144892
- * @return {Array<Variable>} a list of process variables
144893
- *
144894
- * The following example contains one variable
144895
- *
144896
- * @example
144897
- * VariableProvider.getVariables = function(element) {
144898
- * const variables = [
144899
- * {
144900
- * name: 'myVariable',
144901
- * type: 'String',
144902
- * info: 'This is a global variable'
144903
- * }
144904
- * ];
144905
- *
144906
- * if (is(element, 'bpmn:Process')) {
144907
- * return variables;
144908
- * }
144909
- * }
144910
- */
144911
- getVariables(element) { }
144912
-
144913
- register() {
144914
- this._variableResolver.registerProvider(this);
144915
- }
144916
- }
144917
-
144918
144925
  VariableProvider.$inject = [ 'variableResolver' ];
144919
144926
 
144920
- /**
144921
- * TODO: This method tries to mirror the behavior of ConnectorMappings. However, this is not possible in all cases,
144922
- * as the absence of the header has execution implications. This should be replaced with engine behavior in the
144923
- * Connector Implementation at one point.
144924
- */
144925
- class ConnectorVariableProvider extends VariableProvider {
144926
- getVariables(element) {
144927
-
144928
- const result = [];
144929
-
144930
- const taskheaders = getExtensionElementsList(element, 'zeebe:TaskHeaders')[0];
144931
-
144932
- if (!taskheaders || !taskheaders.values) {
144933
- return;
144934
- }
144935
-
144936
- const headers = taskheaders.values;
144937
-
144938
- const resultVariable = headers.find(header => {
144939
- return header.key === 'resultVariable';
144940
- });
144941
-
144942
- const resultExpression = headers.find(header => {
144943
- return header.key === 'resultExpression';
144944
- });
144945
-
144946
- if (resultVariable && resultVariable.value) {
144947
- result.push({
144948
- name: resultVariable.value
144949
- });
144950
- }
144951
-
144952
- if (resultExpression && resultExpression.value) {
144953
-
144954
- // parse with FEEL
144955
- const resultContext = getResultContext(resultExpression.value.substring(1));
144956
-
144957
- const expressionVariables = toUnifiedFormat(resultContext.computedValue());
144958
-
144959
- if (expressionVariables && expressionVariables.length > 0) {
144960
- result.push(
144961
- ...expressionVariables[0].entries
144962
- );
144963
- }
144964
- }
144965
-
144966
- return result;
144967
- }
144927
+ /**
144928
+ * TODO: This method tries to mirror the behavior of ConnectorMappings. However, this is not possible in all cases,
144929
+ * as the absence of the header has execution implications. This should be replaced with engine behavior in the
144930
+ * Connector Implementation at one point.
144931
+ */
144932
+ class ConnectorVariableProvider extends VariableProvider {
144933
+ getVariables(element) {
144934
+
144935
+ const result = [];
144936
+
144937
+ const taskheaders = getExtensionElementsList(element, 'zeebe:TaskHeaders')[0];
144938
+
144939
+ if (!taskheaders || !taskheaders.values) {
144940
+ return;
144941
+ }
144942
+
144943
+ const headers = taskheaders.values;
144944
+
144945
+ const resultVariable = headers.find(header => {
144946
+ return header.key === 'resultVariable';
144947
+ });
144948
+
144949
+ const resultExpression = headers.find(header => {
144950
+ return header.key === 'resultExpression';
144951
+ });
144952
+
144953
+ if (resultVariable && resultVariable.value) {
144954
+ result.push({
144955
+ name: resultVariable.value
144956
+ });
144957
+ }
144958
+
144959
+ if (resultExpression && resultExpression.value) {
144960
+
144961
+ // parse with FEEL
144962
+ const resultContext = getResultContext(resultExpression.value.substring(1));
144963
+
144964
+ const expressionVariables = toUnifiedFormat(resultContext.computedValue());
144965
+
144966
+ if (expressionVariables && expressionVariables.length > 0) {
144967
+ result.push(
144968
+ ...expressionVariables[0].entries
144969
+ );
144970
+ }
144971
+ }
144972
+
144973
+ return result;
144974
+ }
144968
144975
  }
144969
144976
 
144970
- const ZeebeVariableResolverModule = {
144971
- __init__: [
144972
- 'variableResolver',
144973
- 'connectorVariableProvider'
144974
- ],
144975
- variableResolver: [ 'type', ZeebeVariableResolver ],
144976
- connectorVariableProvider: [ 'type', ConnectorVariableProvider ]
144977
+ const ZeebeVariableResolverModule = {
144978
+ __init__: [
144979
+ 'variableResolver',
144980
+ 'connectorVariableProvider'
144981
+ ],
144982
+ variableResolver: [ 'type', ZeebeVariableResolver ],
144983
+ connectorVariableProvider: [ 'type', ConnectorVariableProvider ]
144977
144984
  };
144978
144985
 
144979
144986
  const EXAMPLE_JSON_PROPERTY_NAME = 'camundaModeler:exampleOutputJson';