@bpmn-io/form-js-viewer 1.24.0 → 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.es.js CHANGED
@@ -39,7 +39,26 @@ const getFlavouredFeelVariableNames = (feelString, feelFlavour = 'expression', o
39
39
  // if using special depth accessors, use a more complex extraction
40
40
  return Array.from(_smartExtractVariableNames(node, depth, specialDepthAccessors));
41
41
  }
42
- if (depth === 0 && node.name === 'VariableName') return [node.variableName];
42
+ if (depth === 0 && node.name === 'VariableName') return [_cleanupVariableName(node.variableName)];
43
+
44
+ // skip function names - the function name is the only direct VariableName child of a
45
+ // FunctionInvocation (arguments are nested under Positional/NamedParameters), so drop it
46
+ if (node.name === 'FunctionInvocation') {
47
+ const args = node.children.filter(child => child.name !== 'VariableName');
48
+ return args.reduce((acc, child) => acc.concat(_unfoldVariables(child)), []);
49
+ }
50
+
51
+ // skip type names in instance of expressions
52
+ if (node.name === 'Type') {
53
+ return [];
54
+ }
55
+
56
+ // handle quantified (some...satisfies) and for expressions - exclude bound iteration variables
57
+ if (node.name === 'QuantifiedExpression' || node.name === 'ForExpression') {
58
+ const boundNames = _collectBoundVariableNames(node);
59
+ const variables = node.children.reduce((acc, child) => acc.concat(_unfoldVariables(child)), []);
60
+ return variables.filter(name => !boundNames.includes(name));
61
+ }
43
62
 
44
63
  // for any other kind of node, traverse its children and flatten the result
45
64
  if (node.children) {
@@ -164,6 +183,9 @@ const _buildSimpleFeelStructureTree = (parseTree, feelString) => {
164
183
  if (node.type.name === 'VariableName') {
165
184
  nodeRepresentation.variableName = feelString.slice(node.from, node.to);
166
185
  }
186
+ if (node.type.name === 'Name') {
187
+ nodeRepresentation.variableName = feelString.slice(node.from, node.to);
188
+ }
167
189
  stack.push(nodeRepresentation);
168
190
  },
169
191
  leave: () => {
@@ -213,6 +235,53 @@ const _extractFilterExpressions = tree => {
213
235
  return flattenedExpressionTree;
214
236
  };
215
237
 
238
+ /**
239
+ * FEEL keywords that may be incorrectly absorbed into variable names by the parser.
240
+ * For example, `variable1 not in (...)` parses as VariableName "variable1 not".
241
+ */
242
+ const FEEL_TRAILING_KEYWORDS = ['not'];
243
+
244
+ /**
245
+ * Cleans up a variable name by stripping trailing FEEL keywords that the parser
246
+ * may have incorrectly included as part of the variable name.
247
+ *
248
+ * @param {string} variableName - The raw variable name from the parse tree.
249
+ * @returns {string} The cleaned variable name.
250
+ */
251
+ const _cleanupVariableName = variableName => {
252
+ for (const keyword of FEEL_TRAILING_KEYWORDS) {
253
+ if (variableName.endsWith(' ' + keyword)) {
254
+ return variableName.slice(0, -(keyword.length + 1));
255
+ }
256
+ }
257
+ return variableName;
258
+ };
259
+
260
+ /**
261
+ * Collects the names of variables bound by iteration constructs (e.g. `for x in ...`, `some x in ...`).
262
+ * These are locally scoped and should be excluded from the extracted variable set.
263
+ *
264
+ * @param {Object} node - A QuantifiedExpression or ForExpression node.
265
+ * @returns {string[]} The bound variable names.
266
+ */
267
+ const _collectBoundVariableNames = node => {
268
+ const boundNames = [];
269
+ const collect = n => {
270
+ if (n.name === 'InExpression') {
271
+ // The Name node inside an InExpression is the bound iteration variable
272
+ const nameNode = n.children.find(child => child.name === 'Name');
273
+ if (nameNode && nameNode.variableName) {
274
+ boundNames.push(nameNode.variableName);
275
+ }
276
+ }
277
+ if (n.children) {
278
+ n.children.forEach(collect);
279
+ }
280
+ };
281
+ collect(node);
282
+ return boundNames;
283
+ };
284
+
216
285
  class FeelExpressionLanguage {
217
286
  constructor(eventBus) {
218
287
  this._eventBus = eventBus;
@@ -6071,11 +6140,10 @@ function DocumentPreview(props) {
6071
6140
  if (!isValidDocumentEndpoint(finalEndpoint)) {
6072
6141
  return null;
6073
6142
  }
6074
- const requestInit = getDocumentRequestInit(documentEndpointBuilder, document);
6075
6143
  return jsx(DocumentRenderer, {
6076
6144
  documentMetadata: document,
6145
+ documentEndpointBuilder: documentEndpointBuilder,
6077
6146
  endpoint: finalEndpoint,
6078
- requestInit: requestInit,
6079
6147
  maxHeight: maxHeight,
6080
6148
  domId: `${domId}-${index}`
6081
6149
  }, document.documentId);
@@ -6257,9 +6325,9 @@ function ImageRenderer(props) {
6257
6325
  *
6258
6326
  * @param {Object} props
6259
6327
  * @param {DocumentMetadata} props.documentMetadata
6328
+ * @param {DocumentEndpointBuilder | null} props.documentEndpointBuilder
6260
6329
  * @param {string} props.endpoint
6261
6330
  * @param {string} props.domId
6262
- * @param {RequestInit|undefined} props.requestInit
6263
6331
  * @param {number|undefined} props.maxHeight
6264
6332
  *
6265
6333
  * @returns {import("preact").JSX.Element}
@@ -6267,10 +6335,10 @@ function ImageRenderer(props) {
6267
6335
  function DocumentRenderer(props) {
6268
6336
  const {
6269
6337
  documentMetadata,
6338
+ documentEndpointBuilder,
6270
6339
  endpoint,
6271
6340
  maxHeight,
6272
- domId,
6273
- requestInit
6341
+ domId
6274
6342
  } = props;
6275
6343
  const {
6276
6344
  metadata
@@ -6278,6 +6346,8 @@ function DocumentRenderer(props) {
6278
6346
  const [hasError, setHasError] = useState(false);
6279
6347
  const ref = useRef(null);
6280
6348
  const isInViewport = useInViewport(ref);
6349
+ const onError = useCallback(() => setHasError(true), []);
6350
+ const requestInit = useMemo(() => getDocumentRequestInit(documentEndpointBuilder, documentMetadata), [documentEndpointBuilder, documentMetadata]);
6281
6351
  const singleDocumentContainerClassName = `fjs-${type}-single-document-container`;
6282
6352
  const errorMessageId = `${domId}-error-message`;
6283
6353
  const errorMessage = 'Unable to download document';
@@ -6293,14 +6363,12 @@ function DocumentRenderer(props) {
6293
6363
  url: endpoint,
6294
6364
  alt: metadata.fileName,
6295
6365
  requestInit: requestInit,
6296
- onError: () => setHasError(true)
6366
+ onError: onError
6297
6367
  }), jsx(DownloadButton, {
6298
6368
  endpoint: endpoint,
6299
6369
  fileName: metadata.fileName,
6300
6370
  requestInit: requestInit,
6301
- onDownloadError: () => {
6302
- setHasError(true);
6303
- }
6371
+ onDownloadError: onError
6304
6372
  }), hasError ? jsx(Errors, {
6305
6373
  id: errorMessageId,
6306
6374
  errors: [errorMessage]
@@ -6318,7 +6386,7 @@ function DocumentRenderer(props) {
6318
6386
  url: endpoint,
6319
6387
  fileName: metadata.fileName,
6320
6388
  requestInit: requestInit,
6321
- onError: () => setHasError(true),
6389
+ onError: onError,
6322
6390
  errorMessageId: errorMessageId
6323
6391
  })
6324
6392
  });
@@ -6339,9 +6407,7 @@ function DocumentRenderer(props) {
6339
6407
  endpoint: endpoint,
6340
6408
  fileName: metadata.fileName,
6341
6409
  requestInit: requestInit,
6342
- onDownloadError: () => {
6343
- setHasError(true);
6344
- }
6410
+ onDownloadError: onError
6345
6411
  })]
6346
6412
  });
6347
6413
  }