@bpmn-io/form-js-viewer 1.23.1 → 1.24.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -59,7 +59,26 @@ const getFlavouredFeelVariableNames = (feelString, feelFlavour = 'expression', o
59
59
  // if using special depth accessors, use a more complex extraction
60
60
  return Array.from(_smartExtractVariableNames(node, depth, specialDepthAccessors));
61
61
  }
62
- if (depth === 0 && node.name === 'VariableName') return [node.variableName];
62
+ if (depth === 0 && node.name === 'VariableName') return [_cleanupVariableName(node.variableName)];
63
+
64
+ // skip function names - the function name is the only direct VariableName child of a
65
+ // FunctionInvocation (arguments are nested under Positional/NamedParameters), so drop it
66
+ if (node.name === 'FunctionInvocation') {
67
+ const args = node.children.filter(child => child.name !== 'VariableName');
68
+ return args.reduce((acc, child) => acc.concat(_unfoldVariables(child)), []);
69
+ }
70
+
71
+ // skip type names in instance of expressions
72
+ if (node.name === 'Type') {
73
+ return [];
74
+ }
75
+
76
+ // handle quantified (some...satisfies) and for expressions - exclude bound iteration variables
77
+ if (node.name === 'QuantifiedExpression' || node.name === 'ForExpression') {
78
+ const boundNames = _collectBoundVariableNames(node);
79
+ const variables = node.children.reduce((acc, child) => acc.concat(_unfoldVariables(child)), []);
80
+ return variables.filter(name => !boundNames.includes(name));
81
+ }
63
82
 
64
83
  // for any other kind of node, traverse its children and flatten the result
65
84
  if (node.children) {
@@ -184,6 +203,9 @@ const _buildSimpleFeelStructureTree = (parseTree, feelString) => {
184
203
  if (node.type.name === 'VariableName') {
185
204
  nodeRepresentation.variableName = feelString.slice(node.from, node.to);
186
205
  }
206
+ if (node.type.name === 'Name') {
207
+ nodeRepresentation.variableName = feelString.slice(node.from, node.to);
208
+ }
187
209
  stack.push(nodeRepresentation);
188
210
  },
189
211
  leave: () => {
@@ -233,6 +255,53 @@ const _extractFilterExpressions = tree => {
233
255
  return flattenedExpressionTree;
234
256
  };
235
257
 
258
+ /**
259
+ * FEEL keywords that may be incorrectly absorbed into variable names by the parser.
260
+ * For example, `variable1 not in (...)` parses as VariableName "variable1 not".
261
+ */
262
+ const FEEL_TRAILING_KEYWORDS = ['not'];
263
+
264
+ /**
265
+ * Cleans up a variable name by stripping trailing FEEL keywords that the parser
266
+ * may have incorrectly included as part of the variable name.
267
+ *
268
+ * @param {string} variableName - The raw variable name from the parse tree.
269
+ * @returns {string} The cleaned variable name.
270
+ */
271
+ const _cleanupVariableName = variableName => {
272
+ for (const keyword of FEEL_TRAILING_KEYWORDS) {
273
+ if (variableName.endsWith(' ' + keyword)) {
274
+ return variableName.slice(0, -(keyword.length + 1));
275
+ }
276
+ }
277
+ return variableName;
278
+ };
279
+
280
+ /**
281
+ * Collects the names of variables bound by iteration constructs (e.g. `for x in ...`, `some x in ...`).
282
+ * These are locally scoped and should be excluded from the extracted variable set.
283
+ *
284
+ * @param {Object} node - A QuantifiedExpression or ForExpression node.
285
+ * @returns {string[]} The bound variable names.
286
+ */
287
+ const _collectBoundVariableNames = node => {
288
+ const boundNames = [];
289
+ const collect = n => {
290
+ if (n.name === 'InExpression') {
291
+ // The Name node inside an InExpression is the bound iteration variable
292
+ const nameNode = n.children.find(child => child.name === 'Name');
293
+ if (nameNode && nameNode.variableName) {
294
+ boundNames.push(nameNode.variableName);
295
+ }
296
+ }
297
+ if (n.children) {
298
+ n.children.forEach(collect);
299
+ }
300
+ };
301
+ collect(node);
302
+ return boundNames;
303
+ };
304
+
236
305
  class FeelExpressionLanguage {
237
306
  constructor(eventBus) {
238
307
  this._eventBus = eventBus;
@@ -5881,7 +5950,7 @@ const EMPTY_ARRAY$1 = [];
5881
5950
  * @returns {import("preact").JSX.Element}
5882
5951
  */
5883
5952
  function FilePicker(props) {
5884
- /** @type {import("preact/hooks").Ref<HTMLInputElement>} */
5953
+ /** @type {import("preact").RefObject<HTMLInputElement>} */
5885
5954
  const fileInputRef = hooks.useRef(null);
5886
5955
  /** @type {import('../../FileRegistry').FileRegistry} */
5887
5956
  const fileRegistry = useService('fileRegistry', false);
@@ -5971,7 +6040,6 @@ function FilePicker(props) {
5971
6040
  children: [jsxRuntime.jsx("button", {
5972
6041
  type: "button",
5973
6042
  disabled: isInputDisabled,
5974
- readOnly: readonly,
5975
6043
  className: "fjs-button fjs-filepicker-button",
5976
6044
  onClick: () => {
5977
6045
  fileInputRef.current.click();
@@ -6092,11 +6160,10 @@ function DocumentPreview(props) {
6092
6160
  if (!isValidDocumentEndpoint(finalEndpoint)) {
6093
6161
  return null;
6094
6162
  }
6095
- const requestInit = getDocumentRequestInit(documentEndpointBuilder, document);
6096
6163
  return jsxRuntime.jsx(DocumentRenderer, {
6097
6164
  documentMetadata: document,
6165
+ documentEndpointBuilder: documentEndpointBuilder,
6098
6166
  endpoint: finalEndpoint,
6099
- requestInit: requestInit,
6100
6167
  maxHeight: maxHeight,
6101
6168
  domId: `${domId}-${index}`
6102
6169
  }, document.documentId);
@@ -6278,9 +6345,9 @@ function ImageRenderer(props) {
6278
6345
  *
6279
6346
  * @param {Object} props
6280
6347
  * @param {DocumentMetadata} props.documentMetadata
6348
+ * @param {DocumentEndpointBuilder | null} props.documentEndpointBuilder
6281
6349
  * @param {string} props.endpoint
6282
6350
  * @param {string} props.domId
6283
- * @param {RequestInit|undefined} props.requestInit
6284
6351
  * @param {number|undefined} props.maxHeight
6285
6352
  *
6286
6353
  * @returns {import("preact").JSX.Element}
@@ -6288,10 +6355,10 @@ function ImageRenderer(props) {
6288
6355
  function DocumentRenderer(props) {
6289
6356
  const {
6290
6357
  documentMetadata,
6358
+ documentEndpointBuilder,
6291
6359
  endpoint,
6292
6360
  maxHeight,
6293
- domId,
6294
- requestInit
6361
+ domId
6295
6362
  } = props;
6296
6363
  const {
6297
6364
  metadata
@@ -6299,6 +6366,8 @@ function DocumentRenderer(props) {
6299
6366
  const [hasError, setHasError] = hooks.useState(false);
6300
6367
  const ref = hooks.useRef(null);
6301
6368
  const isInViewport = useInViewport(ref);
6369
+ const onError = hooks.useCallback(() => setHasError(true), []);
6370
+ const requestInit = hooks.useMemo(() => getDocumentRequestInit(documentEndpointBuilder, documentMetadata), [documentEndpointBuilder, documentMetadata]);
6302
6371
  const singleDocumentContainerClassName = `fjs-${type}-single-document-container`;
6303
6372
  const errorMessageId = `${domId}-error-message`;
6304
6373
  const errorMessage = 'Unable to download document';
@@ -6314,14 +6383,12 @@ function DocumentRenderer(props) {
6314
6383
  url: endpoint,
6315
6384
  alt: metadata.fileName,
6316
6385
  requestInit: requestInit,
6317
- onError: () => setHasError(true)
6386
+ onError: onError
6318
6387
  }), jsxRuntime.jsx(DownloadButton, {
6319
6388
  endpoint: endpoint,
6320
6389
  fileName: metadata.fileName,
6321
6390
  requestInit: requestInit,
6322
- onDownloadError: () => {
6323
- setHasError(true);
6324
- }
6391
+ onDownloadError: onError
6325
6392
  }), hasError ? jsxRuntime.jsx(Errors, {
6326
6393
  id: errorMessageId,
6327
6394
  errors: [errorMessage]
@@ -6339,7 +6406,7 @@ function DocumentRenderer(props) {
6339
6406
  url: endpoint,
6340
6407
  fileName: metadata.fileName,
6341
6408
  requestInit: requestInit,
6342
- onError: () => setHasError(true),
6409
+ onError: onError,
6343
6410
  errorMessageId: errorMessageId
6344
6411
  })
6345
6412
  });
@@ -6360,9 +6427,7 @@ function DocumentRenderer(props) {
6360
6427
  endpoint: endpoint,
6361
6428
  fileName: metadata.fileName,
6362
6429
  requestInit: requestInit,
6363
- onDownloadError: () => {
6364
- setHasError(true);
6365
- }
6430
+ onDownloadError: onError
6366
6431
  })]
6367
6432
  });
6368
6433
  }
@@ -7003,10 +7068,10 @@ const MarkdownRendererModule = {
7003
7068
  /**
7004
7069
  * @typedef {import('didi').Injector} Injector
7005
7070
  *
7006
- * @typedef {import('../core/Types').ElementLike} ElementLike
7071
+ * @typedef {import('../core/Types.js').ElementLike} ElementLike
7007
7072
  *
7008
- * @typedef {import('../core/EventBus').default} EventBus
7009
- * @typedef {import('./CommandHandler').default} CommandHandler
7073
+ * @typedef {import('../core/EventBus.js').default} EventBus
7074
+ * @typedef {import('./CommandHandler.js').default} CommandHandler
7010
7075
  *
7011
7076
  * @typedef { any } CommandContext
7012
7077
  * @typedef { {
@@ -7802,7 +7867,6 @@ class RepeatRenderManager {
7802
7867
  }),
7803
7868
  children: [showAdd ? jsxRuntime.jsx("button", {
7804
7869
  type: "button",
7805
- readOnly: readonly,
7806
7870
  disabled: disabled || readonly,
7807
7871
  class: "fjs-repeat-render-add",
7808
7872
  ref: addButtonRef,
@@ -8045,11 +8109,11 @@ function EventBus() {
8045
8109
  *
8046
8110
  * Returning anything but `undefined` from a listener will stop the listener propagation.
8047
8111
  *
8048
- * @template T
8112
+ * @template {keyof EventMap} EventName
8049
8113
  *
8050
- * @param {string|string[]} events to subscribe to
8114
+ * @param {EventName} events to subscribe to
8051
8115
  * @param {number} [priority=1000] listen priority
8052
- * @param {EventBusEventCallback<T>} callback
8116
+ * @param {EventBusEventCallback<EventMap[EventName]>} callback
8053
8117
  * @param {any} [that] callback context
8054
8118
  */
8055
8119
  /**
@@ -8064,11 +8128,11 @@ function EventBus() {
8064
8128
  *
8065
8129
  * Returning anything but `undefined` from a listener will stop the listener propagation.
8066
8130
  *
8067
- * @template {keyof EventMap} EventName
8131
+ * @template T
8068
8132
  *
8069
- * @param {EventName} events to subscribe to
8133
+ * @param {string|string[]} events to subscribe to
8070
8134
  * @param {number} [priority=1000] listen priority
8071
- * @param {EventBusEventCallback<EventMap[EventName]>} callback
8135
+ * @param {EventBusEventCallback<T>} callback
8072
8136
  * @param {any} [that] callback context
8073
8137
  */
8074
8138
  EventBus.prototype.on = function (events, priority, callback, that) {
@@ -8105,21 +8169,21 @@ EventBus.prototype.on = function (events, priority, callback, that) {
8105
8169
  *
8106
8170
  * Register an event listener that is called only once.
8107
8171
  *
8108
- * @template T
8172
+ * @template {keyof EventMap} EventName
8109
8173
  *
8110
- * @param {string|string[]} events to subscribe to
8111
- * @param {number} [priority=1000] the listen priority
8112
- * @param {EventBusEventCallback<T>} callback
8174
+ * @param {EventName} events to subscribe to
8175
+ * @param {number} [priority=1000] listen priority
8176
+ * @param {EventBusEventCallback<EventMap[EventName]>} callback
8113
8177
  * @param {any} [that] callback context
8114
8178
  */
8115
8179
  /**
8116
8180
  * Register an event listener that is called only once.
8117
8181
  *
8118
- * @template {keyof EventMap} EventName
8182
+ * @template T
8119
8183
  *
8120
- * @param {EventName} events to subscribe to
8121
- * @param {number} [priority=1000] listen priority
8122
- * @param {EventBusEventCallback<EventMap[EventName]>} callback
8184
+ * @param {string|string[]} events to subscribe to
8185
+ * @param {number} [priority=1000] the listen priority
8186
+ * @param {EventBusEventCallback<T>} callback
8123
8187
  * @param {any} [that] callback context
8124
8188
  */
8125
8189
  EventBus.prototype.once = function (events, priority, callback, that) {