@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.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;
@@ -5861,7 +5930,7 @@ const EMPTY_ARRAY$1 = [];
5861
5930
  * @returns {import("preact").JSX.Element}
5862
5931
  */
5863
5932
  function FilePicker(props) {
5864
- /** @type {import("preact/hooks").Ref<HTMLInputElement>} */
5933
+ /** @type {import("preact").RefObject<HTMLInputElement>} */
5865
5934
  const fileInputRef = useRef(null);
5866
5935
  /** @type {import('../../FileRegistry').FileRegistry} */
5867
5936
  const fileRegistry = useService('fileRegistry', false);
@@ -5951,7 +6020,6 @@ function FilePicker(props) {
5951
6020
  children: [jsx("button", {
5952
6021
  type: "button",
5953
6022
  disabled: isInputDisabled,
5954
- readOnly: readonly,
5955
6023
  className: "fjs-button fjs-filepicker-button",
5956
6024
  onClick: () => {
5957
6025
  fileInputRef.current.click();
@@ -6072,11 +6140,10 @@ function DocumentPreview(props) {
6072
6140
  if (!isValidDocumentEndpoint(finalEndpoint)) {
6073
6141
  return null;
6074
6142
  }
6075
- const requestInit = getDocumentRequestInit(documentEndpointBuilder, document);
6076
6143
  return jsx(DocumentRenderer, {
6077
6144
  documentMetadata: document,
6145
+ documentEndpointBuilder: documentEndpointBuilder,
6078
6146
  endpoint: finalEndpoint,
6079
- requestInit: requestInit,
6080
6147
  maxHeight: maxHeight,
6081
6148
  domId: `${domId}-${index}`
6082
6149
  }, document.documentId);
@@ -6258,9 +6325,9 @@ function ImageRenderer(props) {
6258
6325
  *
6259
6326
  * @param {Object} props
6260
6327
  * @param {DocumentMetadata} props.documentMetadata
6328
+ * @param {DocumentEndpointBuilder | null} props.documentEndpointBuilder
6261
6329
  * @param {string} props.endpoint
6262
6330
  * @param {string} props.domId
6263
- * @param {RequestInit|undefined} props.requestInit
6264
6331
  * @param {number|undefined} props.maxHeight
6265
6332
  *
6266
6333
  * @returns {import("preact").JSX.Element}
@@ -6268,10 +6335,10 @@ function ImageRenderer(props) {
6268
6335
  function DocumentRenderer(props) {
6269
6336
  const {
6270
6337
  documentMetadata,
6338
+ documentEndpointBuilder,
6271
6339
  endpoint,
6272
6340
  maxHeight,
6273
- domId,
6274
- requestInit
6341
+ domId
6275
6342
  } = props;
6276
6343
  const {
6277
6344
  metadata
@@ -6279,6 +6346,8 @@ function DocumentRenderer(props) {
6279
6346
  const [hasError, setHasError] = useState(false);
6280
6347
  const ref = useRef(null);
6281
6348
  const isInViewport = useInViewport(ref);
6349
+ const onError = useCallback(() => setHasError(true), []);
6350
+ const requestInit = useMemo(() => getDocumentRequestInit(documentEndpointBuilder, documentMetadata), [documentEndpointBuilder, documentMetadata]);
6282
6351
  const singleDocumentContainerClassName = `fjs-${type}-single-document-container`;
6283
6352
  const errorMessageId = `${domId}-error-message`;
6284
6353
  const errorMessage = 'Unable to download document';
@@ -6294,14 +6363,12 @@ function DocumentRenderer(props) {
6294
6363
  url: endpoint,
6295
6364
  alt: metadata.fileName,
6296
6365
  requestInit: requestInit,
6297
- onError: () => setHasError(true)
6366
+ onError: onError
6298
6367
  }), jsx(DownloadButton, {
6299
6368
  endpoint: endpoint,
6300
6369
  fileName: metadata.fileName,
6301
6370
  requestInit: requestInit,
6302
- onDownloadError: () => {
6303
- setHasError(true);
6304
- }
6371
+ onDownloadError: onError
6305
6372
  }), hasError ? jsx(Errors, {
6306
6373
  id: errorMessageId,
6307
6374
  errors: [errorMessage]
@@ -6319,7 +6386,7 @@ function DocumentRenderer(props) {
6319
6386
  url: endpoint,
6320
6387
  fileName: metadata.fileName,
6321
6388
  requestInit: requestInit,
6322
- onError: () => setHasError(true),
6389
+ onError: onError,
6323
6390
  errorMessageId: errorMessageId
6324
6391
  })
6325
6392
  });
@@ -6340,9 +6407,7 @@ function DocumentRenderer(props) {
6340
6407
  endpoint: endpoint,
6341
6408
  fileName: metadata.fileName,
6342
6409
  requestInit: requestInit,
6343
- onDownloadError: () => {
6344
- setHasError(true);
6345
- }
6410
+ onDownloadError: onError
6346
6411
  })]
6347
6412
  });
6348
6413
  }
@@ -6983,10 +7048,10 @@ const MarkdownRendererModule = {
6983
7048
  /**
6984
7049
  * @typedef {import('didi').Injector} Injector
6985
7050
  *
6986
- * @typedef {import('../core/Types').ElementLike} ElementLike
7051
+ * @typedef {import('../core/Types.js').ElementLike} ElementLike
6987
7052
  *
6988
- * @typedef {import('../core/EventBus').default} EventBus
6989
- * @typedef {import('./CommandHandler').default} CommandHandler
7053
+ * @typedef {import('../core/EventBus.js').default} EventBus
7054
+ * @typedef {import('./CommandHandler.js').default} CommandHandler
6990
7055
  *
6991
7056
  * @typedef { any } CommandContext
6992
7057
  * @typedef { {
@@ -7782,7 +7847,6 @@ class RepeatRenderManager {
7782
7847
  }),
7783
7848
  children: [showAdd ? jsx("button", {
7784
7849
  type: "button",
7785
- readOnly: readonly,
7786
7850
  disabled: disabled || readonly,
7787
7851
  class: "fjs-repeat-render-add",
7788
7852
  ref: addButtonRef,
@@ -8025,11 +8089,11 @@ function EventBus() {
8025
8089
  *
8026
8090
  * Returning anything but `undefined` from a listener will stop the listener propagation.
8027
8091
  *
8028
- * @template T
8092
+ * @template {keyof EventMap} EventName
8029
8093
  *
8030
- * @param {string|string[]} events to subscribe to
8094
+ * @param {EventName} events to subscribe to
8031
8095
  * @param {number} [priority=1000] listen priority
8032
- * @param {EventBusEventCallback<T>} callback
8096
+ * @param {EventBusEventCallback<EventMap[EventName]>} callback
8033
8097
  * @param {any} [that] callback context
8034
8098
  */
8035
8099
  /**
@@ -8044,11 +8108,11 @@ function EventBus() {
8044
8108
  *
8045
8109
  * Returning anything but `undefined` from a listener will stop the listener propagation.
8046
8110
  *
8047
- * @template {keyof EventMap} EventName
8111
+ * @template T
8048
8112
  *
8049
- * @param {EventName} events to subscribe to
8113
+ * @param {string|string[]} events to subscribe to
8050
8114
  * @param {number} [priority=1000] listen priority
8051
- * @param {EventBusEventCallback<EventMap[EventName]>} callback
8115
+ * @param {EventBusEventCallback<T>} callback
8052
8116
  * @param {any} [that] callback context
8053
8117
  */
8054
8118
  EventBus.prototype.on = function (events, priority, callback, that) {
@@ -8085,21 +8149,21 @@ EventBus.prototype.on = function (events, priority, callback, that) {
8085
8149
  *
8086
8150
  * Register an event listener that is called only once.
8087
8151
  *
8088
- * @template T
8152
+ * @template {keyof EventMap} EventName
8089
8153
  *
8090
- * @param {string|string[]} events to subscribe to
8091
- * @param {number} [priority=1000] the listen priority
8092
- * @param {EventBusEventCallback<T>} callback
8154
+ * @param {EventName} events to subscribe to
8155
+ * @param {number} [priority=1000] listen priority
8156
+ * @param {EventBusEventCallback<EventMap[EventName]>} callback
8093
8157
  * @param {any} [that] callback context
8094
8158
  */
8095
8159
  /**
8096
8160
  * Register an event listener that is called only once.
8097
8161
  *
8098
- * @template {keyof EventMap} EventName
8162
+ * @template T
8099
8163
  *
8100
- * @param {EventName} events to subscribe to
8101
- * @param {number} [priority=1000] listen priority
8102
- * @param {EventBusEventCallback<EventMap[EventName]>} callback
8164
+ * @param {string|string[]} events to subscribe to
8165
+ * @param {number} [priority=1000] the listen priority
8166
+ * @param {EventBusEventCallback<T>} callback
8103
8167
  * @param {any} [that] callback context
8104
8168
  */
8105
8169
  EventBus.prototype.once = function (events, priority, callback, that) {