@bpmn-io/form-js-viewer 1.20.0 → 1.21.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
@@ -260,16 +260,38 @@ class FeelExpressionLanguage {
260
260
  * @returns {any}
261
261
  */
262
262
  evaluate(expression, data = {}) {
263
- if (!expression) {
263
+ if (!this.isExpression(expression)) {
264
+ return null;
265
+ }
266
+ try {
267
+ const {
268
+ value: result
269
+ } = evaluate(expression.slice(1), data);
270
+ return result;
271
+ } catch (error) {
272
+ this._eventBus.fire('error', {
273
+ error
274
+ });
264
275
  return null;
265
276
  }
266
- if (!isString(expression) || !expression.startsWith('=')) {
277
+ }
278
+
279
+ /**
280
+ * Evaluate a unary test expression. Returns null for invalid/missing expressions.
281
+ *
282
+ * @param {string} expression
283
+ * @param {import('../../types').Data} [data]
284
+ *
285
+ * @returns {boolean|null}
286
+ */
287
+ evaluateUnaryTest(expression, data = {}) {
288
+ if (!this.isExpression(expression)) {
267
289
  return null;
268
290
  }
269
291
  try {
270
292
  const {
271
293
  value: result
272
- } = evaluate(expression.slice(1), data);
294
+ } = unaryTest(expression.slice(1), data);
273
295
  return result;
274
296
  } catch (error) {
275
297
  this._eventBus.fire('error', {
@@ -598,6 +620,110 @@ function prefixId(id, formId, indexes) {
598
620
  return result;
599
621
  }
600
622
 
623
+ /**
624
+ * Returns the options data for the provided if they can be simply determined, ignoring expression defined options.
625
+ *
626
+ * @param {object} formField
627
+ * @param {object} formData
628
+ */
629
+ function getSimpleOptionsData(formField, formData) {
630
+ const {
631
+ valuesExpression: optionsExpression,
632
+ valuesKey: optionsKey,
633
+ values: staticOptions
634
+ } = formField;
635
+ if (optionsExpression) {
636
+ return null;
637
+ }
638
+ return optionsKey ? get(formData, [optionsKey]) : staticOptions;
639
+ }
640
+
641
+ /**
642
+ * Normalizes the provided options data to a format that can be used by the select components.
643
+ * If the options data is not valid, it is filtered out.
644
+ *
645
+ * @param {any[]} optionsData
646
+ *
647
+ * @returns {object[]}
648
+ */
649
+ function normalizeOptionsData(optionsData) {
650
+ return optionsData.filter(_isAllowedValue).map(_normalizeOption).filter(o => !isNil(o));
651
+ }
652
+
653
+ /**
654
+ * Creates an options object with default values if no options are provided.
655
+ *
656
+ * @param {object} options
657
+ *
658
+ * @returns {object}
659
+ */
660
+ function createEmptyOptions(options = {}) {
661
+ const defaults = {};
662
+
663
+ // provide default options if valuesKey and valuesExpression are not set
664
+ if (!options.valuesKey && !options.valuesExpression) {
665
+ defaults.values = [{
666
+ label: 'Value',
667
+ value: 'value'
668
+ }];
669
+ }
670
+ return {
671
+ ...defaults,
672
+ ...options
673
+ };
674
+ }
675
+
676
+ /**
677
+ * Converts the provided option to a normalized format.
678
+ * If the option is not valid, null is returned.
679
+ *
680
+ * @param {object} option
681
+ * @param {string} option.label
682
+ * @param {*} option.value
683
+ *
684
+ * @returns
685
+ */
686
+ function _normalizeOption(option) {
687
+ // (1) simple primitive case, use it as both label and value
688
+ if (_isAllowedPrimitive(option)) {
689
+ return {
690
+ value: option,
691
+ label: `${option}`
692
+ };
693
+ }
694
+ if (isObject(option)) {
695
+ const isValidLabel = _isValidLabel(option.label);
696
+
697
+ // (2) no label provided, but value is a simple primitive, use it as label and value
698
+ if (!isValidLabel && _isAllowedPrimitive(option.value)) {
699
+ return {
700
+ value: option.value,
701
+ label: `${option.value}`
702
+ };
703
+ }
704
+
705
+ // (3) both label and value are provided, use them as is
706
+ if (isValidLabel && _isAllowedValue(option.value)) {
707
+ return option;
708
+ }
709
+ }
710
+ return null;
711
+ }
712
+ function _isAllowedPrimitive(value) {
713
+ const isAllowedPrimitiveType = ['number', 'string', 'boolean'].includes(typeof value);
714
+ const isValid = value || value === 0 || value === false;
715
+ return isAllowedPrimitiveType && isValid;
716
+ }
717
+ function _isValidLabel(label) {
718
+ return label && isString(label);
719
+ }
720
+ function _isAllowedValue(value) {
721
+ if (isObject(value)) {
722
+ return Object.keys(value).length > 0;
723
+ }
724
+ return _isAllowedPrimitive(value);
725
+ }
726
+
601
727
  const FormRenderContext = createContext({
602
728
  Empty: props => {
603
729
  return null;
@@ -638,7 +764,8 @@ const FormRenderContext = createContext({
638
764
  },
639
765
  hoverInfo: {
640
766
  cleanup: () => {}
641
- }
767
+ },
768
+ applyVisibilityConditions: true
642
769
  });
643
770
 
644
771
  const LocalExpressionContext = createContext({
@@ -746,135 +873,29 @@ function buildExpressionContext(context) {
746
873
  /**
747
874
  * If the value is a valid expression, it is evaluated and returned. Otherwise, it is returned as-is.
748
875
  *
749
- * @param {any} expressionLanguage - The expression language to use.
876
+ * @param {import('../types').ExpressionLanguage} expressionLanguage - The expression language to use.
750
877
  * @param {any} value - The static value or expression to evaluate.
751
878
  * @param {Object} expressionContextInfo - The context information to use.
752
879
  * @returns {any} - Evaluated value or the original value if not an expression.
753
880
  */
754
881
  function runExpressionEvaluation(expressionLanguage, value, expressionContextInfo) {
755
- if (expressionLanguage && expressionLanguage.isExpression(value)) {
882
+ if (expressionLanguage.isExpression(value)) {
756
883
  return expressionLanguage.evaluate(value, buildExpressionContext(expressionContextInfo));
757
884
  }
758
885
  return value;
759
886
  }
760
887
 
761
888
  /**
762
- * Evaluate if condition is met reactively based on the conditionChecker and form data.
763
- *
764
- * @param {string | undefined} condition
765
- *
766
- * @returns {boolean} true if condition is met or no condition or condition checker exists
767
- */
768
- function useCondition(condition) {
769
- const conditionChecker = useService('conditionChecker', false);
770
- const expressionContextInfo = useContext(LocalExpressionContext);
771
- return useMemo(() => {
772
- return conditionChecker ? conditionChecker.check(condition, buildExpressionContext(expressionContextInfo)) : null;
773
- }, [conditionChecker, condition, expressionContextInfo]);
774
- }
775
-
776
- /**
777
- * Returns the options data for the provided if they can be simply determined, ignoring expression defined options.
778
- *
779
- * @param {object} formField
780
- * @param {object} formData
781
- */
782
- function getSimpleOptionsData(formField, formData) {
783
- const {
784
- valuesExpression: optionsExpression,
785
- valuesKey: optionsKey,
786
- values: staticOptions
787
- } = formField;
788
- if (optionsExpression) {
789
- return null;
790
- }
791
- return optionsKey ? get(formData, [optionsKey]) : staticOptions;
792
- }
793
-
794
- /**
795
- * Normalizes the provided options data to a format that can be used by the select components.
796
- * If the options data is not valid, it is filtered out.
797
- *
798
- * @param {any[]} optionsData
799
- *
800
- * @returns {object[]}
801
- */
802
- function normalizeOptionsData(optionsData) {
803
- return optionsData.filter(_isAllowedValue).map(_normalizeOption).filter(o => !isNil(o));
804
- }
805
-
806
- /**
807
- * Creates an options object with default values if no options are provided.
808
- *
809
- * @param {object} options
810
- *
811
- * @returns {object}
812
- */
813
- function createEmptyOptions(options = {}) {
814
- const defaults = {};
815
-
816
- // provide default options if valuesKey and valuesExpression are not set
817
- if (!options.valuesKey && !options.valuesExpression) {
818
- defaults.values = [{
819
- label: 'Value',
820
- value: 'value'
821
- }];
822
- }
823
- return {
824
- ...defaults,
825
- ...options
826
- };
827
- }
828
-
829
- /**
830
- * Converts the provided option to a normalized format.
831
- * If the option is not valid, null is returned.
832
- *
833
- * @param {object} option
834
- * @param {string} option.label
835
- * @param {*} option.value
889
+ * Evaluate a value as a unary test expression. Returns null for invalid/missing expressions or
890
+ * if the expression language is not available.
836
891
  *
837
- * @returns
892
+ * @param {import('../types').ExpressionLanguage} expressionLanguage - The expression language to use.
893
+ * @param {string} value - The unary test expression to evaluate.
894
+ * @param {Object} expressionContextInfo - The context information to use.
895
+ * @returns {boolean | null} - Evaluated result, or null if expression is invalid/missing.
838
896
  */
839
- function _normalizeOption(option) {
840
- // (1) simple primitive case, use it as both label and value
841
- if (_isAllowedPrimitive(option)) {
842
- return {
843
- value: option,
844
- label: `${option}`
845
- };
846
- }
847
- if (isObject(option)) {
848
- const isValidLabel = _isValidLabel(option.label);
849
-
850
- // (2) no label provided, but value is a simple primitive, use it as label and value
851
- if (!isValidLabel && _isAllowedPrimitive(option.value)) {
852
- return {
853
- value: option.value,
854
- label: `${option.value}`
855
- };
856
- }
857
-
858
- // (3) both label and value are provided, use them as is
859
- if (isValidLabel && _isAllowedValue(option.value)) {
860
- return option;
861
- }
862
- }
863
- return null;
864
- }
865
- function _isAllowedPrimitive(value) {
866
- const isAllowedPrimitiveType = ['number', 'string', 'boolean'].includes(typeof value);
867
- const isValid = value || value === 0 || value === false;
868
- return isAllowedPrimitiveType && isValid;
869
- }
870
- function _isValidLabel(label) {
871
- return label && isString(label);
872
- }
873
- function _isAllowedValue(value) {
874
- if (isObject(value)) {
875
- return Object.keys(value).length > 0;
876
- }
877
- return _isAllowedPrimitive(value);
897
+ function runUnaryTestEvaluation(expressionLanguage, value, expressionContextInfo) {
898
+ return expressionLanguage.evaluateUnaryTest(value, buildExpressionContext(expressionContextInfo));
878
899
  }
879
900
 
880
901
  /**
@@ -1208,6 +1229,19 @@ function useBooleanExpressionEvaluation(value) {
1208
1229
  }, [expressionLanguage, expressionContextInfo, value]);
1209
1230
  }
1210
1231
 
1232
+ /**
1233
+ * Evaluate a unary test expression reactively. Returns null for invalid/missing expressions.
1234
+ * The function is memoized to minimize re-renders.
1235
+ *
1236
+ * @param {string | undefined} value - A unary test expression to evaluate.
1237
+ * @returns {boolean | null} - Evaluated result, or null if expression is invalid/missing.
1238
+ */
1239
+ function useUnaryTestEvaluation(value) {
1240
+ const expressionLanguage = useService('expressionLanguage');
1241
+ const expressionContextInfo = useContext(LocalExpressionContext);
1242
+ return useMemo(() => runUnaryTestEvaluation(expressionLanguage, value, expressionContextInfo), [expressionLanguage, expressionContextInfo, value]);
1243
+ }
1244
+
1211
1245
  /**
1212
1246
  * Returns the conditionally filtered data of a form reactively.
1213
1247
  * Memoised to minimize re-renders
@@ -1258,16 +1292,16 @@ function useKeyDownAction(targetKey, action, listenerElement = window) {
1258
1292
  */
1259
1293
  function useReadonly(formField, properties = {}) {
1260
1294
  const expressionLanguage = useService('expressionLanguage');
1261
- const conditionChecker = useService('conditionChecker', false);
1262
- const expressionContextInfo = useContext(LocalExpressionContext);
1263
1295
  const {
1264
1296
  readonly
1265
1297
  } = formField;
1298
+ const isExpression = expressionLanguage && expressionLanguage.isExpression(readonly);
1299
+ const evaluatedReadonly = useUnaryTestEvaluation(isExpression ? readonly : undefined);
1266
1300
  if (properties.readOnly) {
1267
1301
  return true;
1268
1302
  }
1269
- if (expressionLanguage && expressionLanguage.isExpression(readonly)) {
1270
- return conditionChecker ? conditionChecker.check(readonly, buildExpressionContext(expressionContextInfo)) : false;
1303
+ if (isExpression) {
1304
+ return evaluatedReadonly === true;
1271
1305
  }
1272
1306
  return readonly || false;
1273
1307
  }
@@ -2019,7 +2053,8 @@ function FormField(props) {
2019
2053
  const {
2020
2054
  Element,
2021
2055
  Hidden,
2022
- Column
2056
+ Column,
2057
+ applyVisibilityConditions
2023
2058
  } = useContext(FormRenderContext);
2024
2059
  const {
2025
2060
  formId
@@ -2043,7 +2078,8 @@ function FormField(props) {
2043
2078
 
2044
2079
  // add precedence: global readonly > form field disabled
2045
2080
  const disabled = !properties.readOnly && (properties.disabled || field.disabled || false);
2046
- const hidden = useCondition(field.conditional && field.conditional.hide || null);
2081
+ const conditionResult = useUnaryTestEvaluation(field.conditional && field.conditional.hide || null);
2082
+ const hidden = applyVisibilityConditions ? conditionResult : null;
2047
2083
  const instanceId = useMemo(() => {
2048
2084
  if (!formFieldInstanceRegistry) {
2049
2085
  return null;
@@ -5932,7 +5968,8 @@ const type = 'documentPreview';
5932
5968
 
5933
5969
  /**
5934
5970
  * @typedef DocumentEndpointBuilder
5935
- * @property {(document: DocumentMetadata) => string} buildUrl
5971
+ * @property {(document: DocumentMetadata) => string} [buildUrl]
5972
+ * @property {(document: DocumentMetadata) => RequestInit|undefined} [buildRequestInit]
5936
5973
  */
5937
5974
 
5938
5975
  /**
@@ -5983,13 +6020,18 @@ function DocumentPreview(props) {
5983
6020
  class: `fjs-${type}-document-container`,
5984
6021
  id: domId,
5985
6022
  children: data.map((document, index) => {
5986
- const finalEndpoint = tryCatch(() => documentEndpointBuilder?.buildUrl(document)) ?? document.endpoint;
5987
- return isValidDocumentEndpoint(finalEndpoint) ? jsx(DocumentRenderer, {
6023
+ const finalEndpoint = tryCatch(() => documentEndpointBuilder?.buildUrl?.(document)) ?? document.endpoint;
6024
+ if (!isValidDocumentEndpoint(finalEndpoint)) {
6025
+ return null;
6026
+ }
6027
+ const requestInit = getDocumentRequestInit(documentEndpointBuilder, document);
6028
+ return jsx(DocumentRenderer, {
5988
6029
  documentMetadata: document,
5989
6030
  endpoint: finalEndpoint,
6031
+ requestInit: requestInit,
5990
6032
  maxHeight: maxHeight,
5991
6033
  domId: `${domId}-${index}`
5992
- }, document.documentId) : null;
6034
+ }, document.documentId);
5993
6035
  })
5994
6036
  }), jsx(Errors, {
5995
6037
  id: errorMessageId,
@@ -6065,13 +6107,15 @@ function useValidDocumentData(dataSource) {
6065
6107
  * @param {string} props.fileName
6066
6108
  * @param {Function} props.onError
6067
6109
  * @param {string} props.errorMessageId
6110
+ * @param {RequestInit|undefined} props.requestInit
6068
6111
  * @returns {import("preact").JSX.Element}
6069
6112
  */
6070
6113
  function PdfRenderer(props) {
6071
6114
  const {
6072
6115
  url,
6073
6116
  onError,
6074
- errorMessageId
6117
+ errorMessageId,
6118
+ requestInit
6075
6119
  } = props;
6076
6120
  /** @type {ReturnType<typeof import("preact/hooks").useState<null | string>>} */
6077
6121
  const [pdfObjectUrl, setPdfObjectUrl] = useState(null);
@@ -6081,7 +6125,7 @@ function PdfRenderer(props) {
6081
6125
  let objectUrl = null;
6082
6126
  const fetchPdf = async () => {
6083
6127
  try {
6084
- const response = await fetch(url);
6128
+ const response = await fetch(url, requestInit);
6085
6129
  if (!response.ok) {
6086
6130
  setHasError(true);
6087
6131
  onError();
@@ -6101,7 +6145,7 @@ function PdfRenderer(props) {
6101
6145
  URL.revokeObjectURL(objectUrl);
6102
6146
  }
6103
6147
  };
6104
- }, [url, onError]);
6148
+ }, [url, onError, requestInit]);
6105
6149
  return jsxs(Fragment, {
6106
6150
  children: [pdfObjectUrl !== null ? jsx("embed", {
6107
6151
  src: pdfObjectUrl,
@@ -6114,12 +6158,61 @@ function PdfRenderer(props) {
6114
6158
  });
6115
6159
  }
6116
6160
 
6161
+ /**
6162
+ * @param {Object} props
6163
+ * @param {string} props.url
6164
+ * @param {string} props.alt
6165
+ * @param {Function} props.onError
6166
+ * @param {RequestInit|undefined} props.requestInit
6167
+ * @returns {import("preact").JSX.Element}
6168
+ */
6169
+ function ImageRenderer(props) {
6170
+ const {
6171
+ url,
6172
+ alt,
6173
+ onError,
6174
+ requestInit
6175
+ } = props;
6176
+ /** @type {ReturnType<typeof import("preact/hooks").useState<null | string>>} */
6177
+ const [imageObjectUrl, setImageObjectUrl] = useState(null);
6178
+ useEffect(() => {
6179
+ /** @type {null | string} */
6180
+ let objectUrl = null;
6181
+ const fetchImage = async () => {
6182
+ try {
6183
+ const response = await fetch(url, requestInit);
6184
+ if (!response.ok) {
6185
+ onError();
6186
+ return;
6187
+ }
6188
+ const blob = await response.blob();
6189
+ objectUrl = URL.createObjectURL(blob);
6190
+ setImageObjectUrl(objectUrl);
6191
+ } catch {
6192
+ onError();
6193
+ }
6194
+ };
6195
+ fetchImage();
6196
+ return () => {
6197
+ if (objectUrl) {
6198
+ URL.revokeObjectURL(objectUrl);
6199
+ }
6200
+ };
6201
+ }, [url, onError, requestInit]);
6202
+ return imageObjectUrl !== null ? jsx("img", {
6203
+ src: imageObjectUrl,
6204
+ alt: alt,
6205
+ class: `fjs-${type}-image`
6206
+ }) : null;
6207
+ }
6208
+
6117
6209
  /**
6118
6210
  *
6119
6211
  * @param {Object} props
6120
6212
  * @param {DocumentMetadata} props.documentMetadata
6121
6213
  * @param {string} props.endpoint
6122
6214
  * @param {string} props.domId
6215
+ * @param {RequestInit|undefined} props.requestInit
6123
6216
  * @param {number|undefined} props.maxHeight
6124
6217
  *
6125
6218
  * @returns {import("preact").JSX.Element}
@@ -6129,7 +6222,8 @@ function DocumentRenderer(props) {
6129
6222
  documentMetadata,
6130
6223
  endpoint,
6131
6224
  maxHeight,
6132
- domId
6225
+ domId,
6226
+ requestInit
6133
6227
  } = props;
6134
6228
  const {
6135
6229
  metadata
@@ -6148,13 +6242,15 @@ function DocumentRenderer(props) {
6148
6242
  maxHeight
6149
6243
  },
6150
6244
  "aria-describedby": hasError ? errorMessageId : undefined,
6151
- children: [jsx("img", {
6152
- src: endpoint,
6245
+ children: [jsx(ImageRenderer, {
6246
+ url: endpoint,
6153
6247
  alt: metadata.fileName,
6154
- class: `fjs-${type}-image`
6248
+ requestInit: requestInit,
6249
+ onError: () => setHasError(true)
6155
6250
  }), jsx(DownloadButton, {
6156
6251
  endpoint: endpoint,
6157
6252
  fileName: metadata.fileName,
6253
+ requestInit: requestInit,
6158
6254
  onDownloadError: () => {
6159
6255
  setHasError(true);
6160
6256
  }
@@ -6174,6 +6270,7 @@ function DocumentRenderer(props) {
6174
6270
  children: jsx(PdfRenderer, {
6175
6271
  url: endpoint,
6176
6272
  fileName: metadata.fileName,
6273
+ requestInit: requestInit,
6177
6274
  onError: () => setHasError(true),
6178
6275
  errorMessageId: errorMessageId
6179
6276
  })
@@ -6194,6 +6291,7 @@ function DocumentRenderer(props) {
6194
6291
  }), jsx(DownloadButton, {
6195
6292
  endpoint: endpoint,
6196
6293
  fileName: metadata.fileName,
6294
+ requestInit: requestInit,
6197
6295
  onDownloadError: () => {
6198
6296
  setHasError(true);
6199
6297
  }
@@ -6206,6 +6304,7 @@ function DocumentRenderer(props) {
6206
6304
  * @param {string} props.endpoint
6207
6305
  * @param {string} props.fileName
6208
6306
  * @param {Function} props.onDownloadError
6307
+ * @param {RequestInit|undefined} props.requestInit
6209
6308
  *
6210
6309
  * @returns {import("preact").JSX.Element}
6211
6310
  */
@@ -6213,11 +6312,12 @@ function DownloadButton(props) {
6213
6312
  const {
6214
6313
  endpoint,
6215
6314
  fileName,
6216
- onDownloadError
6315
+ onDownloadError,
6316
+ requestInit
6217
6317
  } = props;
6218
6318
  const handleDownload = async () => {
6219
6319
  try {
6220
- const response = await fetch(endpoint);
6320
+ const response = await fetch(endpoint, requestInit);
6221
6321
  if (!response.ok) {
6222
6322
  onDownloadError();
6223
6323
  return;
@@ -6271,6 +6371,16 @@ function useInViewport(ref) {
6271
6371
  return isInViewport;
6272
6372
  }
6273
6373
 
6374
+ /**
6375
+ * @param {DocumentEndpointBuilder | null} documentEndpointBuilder
6376
+ * @param {DocumentMetadata} document
6377
+ * @returns {RequestInit|undefined}
6378
+ */
6379
+ function getDocumentRequestInit(documentEndpointBuilder, document) {
6380
+ const requestInit = tryCatch(() => documentEndpointBuilder?.buildRequestInit?.(document));
6381
+ return requestInit !== null && typeof requestInit === 'object' ? requestInit : undefined;
6382
+ }
6383
+
6274
6384
  /**
6275
6385
  * @template T
6276
6386
  * @param {() => T} fn - Function to execute
@@ -6447,6 +6557,8 @@ const TEMPLATE_PROPERTIES = ['alt', 'appearance.prefixAdorner', 'appearance.suff
6447
6557
 
6448
6558
  /**
6449
6559
  * @typedef { import('../types').Schema } Schema
6560
+ * @typedef { import('../types').ExpressionLanguage } ExpressionLanguage
6561
+ * @typedef { import('../types').Templating } Templating
6450
6562
  */
6451
6563
 
6452
6564
  /**
@@ -6469,8 +6581,8 @@ const TEMPLATE_PROPERTIES = ['alt', 'appearance.prefixAdorner', 'appearance.suff
6469
6581
  *
6470
6582
  * @param {Schema} schema
6471
6583
  * @param {object} [options]
6472
- * @param {any} [options.expressionLanguage]
6473
- * @param {any} [options.templating]
6584
+ * @param {ExpressionLanguage} [options.expressionLanguage]
6585
+ * @param {Templating} [options.templating]
6474
6586
  * @param {any} [options.formFields]
6475
6587
  * @param {boolean} [options.inputs=true]
6476
6588
  * @param {boolean} [options.outputs=true]
@@ -6569,15 +6681,26 @@ const getAncestryList = (formFieldId, formFieldRegistry) => {
6569
6681
  return ids;
6570
6682
  };
6571
6683
 
6684
+ /**
6685
+ * @typedef { import('../../types').ExpressionLanguage } ExpressionLanguage
6686
+ */
6687
+
6572
6688
  /**
6573
6689
  * @typedef {object} Condition
6574
6690
  * @property {string} [hide]
6575
6691
  */
6576
6692
 
6577
6693
  class ConditionChecker {
6578
- constructor(formFieldRegistry, pathRegistry, eventBus) {
6694
+ /**
6695
+ * @param {Object} formFieldRegistry
6696
+ * @param {Object} pathRegistry
6697
+ * @param {ExpressionLanguage} expressionLanguage
6698
+ * @param {Object} eventBus
6699
+ */
6700
+ constructor(formFieldRegistry, pathRegistry, expressionLanguage, eventBus) {
6579
6701
  this._formFieldRegistry = formFieldRegistry;
6580
6702
  this._pathRegistry = pathRegistry;
6703
+ this._expressionLanguage = expressionLanguage;
6581
6704
  this._eventBus = eventBus;
6582
6705
  }
6583
6706
 
@@ -6700,24 +6823,7 @@ class ConditionChecker {
6700
6823
  * @returns {boolean|null}
6701
6824
  */
6702
6825
  check(condition, data = {}) {
6703
- if (!condition) {
6704
- return null;
6705
- }
6706
- if (!isString(condition) || !condition.startsWith('=')) {
6707
- return null;
6708
- }
6709
- try {
6710
- // cut off initial '='
6711
- const {
6712
- value: result
6713
- } = unaryTest(condition.slice(1), data);
6714
- return result;
6715
- } catch (error) {
6716
- this._eventBus.fire('error', {
6717
- error
6718
- });
6719
- return null;
6720
- }
6826
+ return this._expressionLanguage.evaluateUnaryTest(condition, data);
6721
6827
  }
6722
6828
 
6723
6829
  /**
@@ -6751,7 +6857,7 @@ class ConditionChecker {
6751
6857
  return Array.isArray(parentObject) && (!parentObject.length || parentObject.every(item => item === undefined));
6752
6858
  }
6753
6859
  }
6754
- ConditionChecker.$inject = ['formFieldRegistry', 'pathRegistry', 'eventBus'];
6860
+ ConditionChecker.$inject = ['formFieldRegistry', 'pathRegistry', 'expressionLanguage', 'eventBus'];
6755
6861
 
6756
6862
  const ExpressionLanguageModule = {
6757
6863
  __init__: ['expressionLanguage', 'templating', 'conditionChecker'],
@@ -8261,6 +8367,10 @@ function invokeFunction(fn, args) {
8261
8367
  return fn.apply(null, args);
8262
8368
  }
8263
8369
 
8370
+ /**
8371
+ * @typedef { import('../types').ExpressionLanguage } ExpressionLanguage
8372
+ */
8373
+
8264
8374
  const EMAIL_PATTERN = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;
8265
8375
  const PHONE_PATTERN = /(\+|00)(297|93|244|1264|358|355|376|971|54|374|1684|1268|61|43|994|257|32|229|226|880|359|973|1242|387|590|375|501|1441|591|55|1246|673|975|267|236|1|61|41|56|86|225|237|243|242|682|57|269|238|506|53|5999|61|1345|357|420|49|253|1767|45|1809|1829|1849|213|593|20|291|212|34|372|251|358|679|500|33|298|691|241|44|995|44|233|350|224|590|220|245|240|30|1473|299|502|594|1671|592|852|504|385|509|36|62|44|91|246|353|98|964|354|972|39|1876|44|962|81|76|77|254|996|855|686|1869|82|383|965|856|961|231|218|1758|423|94|266|370|352|371|853|590|212|377|373|261|960|52|692|389|223|356|95|382|976|1670|258|222|1664|596|230|265|60|262|264|687|227|672|234|505|683|31|47|977|674|64|968|92|507|64|51|63|680|675|48|1787|1939|850|351|595|970|689|974|262|40|7|250|966|249|221|65|500|4779|677|232|503|378|252|508|381|211|239|597|421|386|46|268|1721|248|963|1649|235|228|66|992|690|993|670|676|1868|216|90|688|886|255|256|380|598|1|998|3906698|379|1784|58|1284|1340|84|678|681|685|967|27|260|263)(9[976]\d|8[987530]\d|6[987]\d|5[90]\d|42\d|3[875]\d|2[98654321]\d|9[8543210]|8[6421]|6[6543210]|5[87654321]|4[987654310]|3[9643210]|2[70]|7|1)\d{4,20}$/;
8266
8376
  const VALIDATE_FEEL_PROPERTIES = ['min', 'max', 'minLength', 'maxLength'];
@@ -8389,6 +8499,12 @@ function runPresetValidation(field, validation, value) {
8389
8499
  }
8390
8500
  return errors;
8391
8501
  }
8502
+
8503
+ /**
8504
+ * @param {Object} validate
8505
+ * @param {ExpressionLanguage} expressionLanguage
8506
+ * @param {Object} expressionContextInfo
8507
+ */
8392
8508
  function evaluateFEELValues(validate, expressionLanguage, expressionContextInfo) {
8393
8509
  const evaluatedValidate = {
8394
8510
  ...validate
@@ -8401,6 +8517,13 @@ function evaluateFEELValues(validate, expressionLanguage, expressionContextInfo)
8401
8517
  });
8402
8518
  return evaluatedValidate;
8403
8519
  }
8520
+
8521
+ /**
8522
+ * @param {Object} validate
8523
+ * @param {ExpressionLanguage} expressionLanguage
8524
+ * @param {Object} conditionChecker
8525
+ * @param {Object} form
8526
+ */
8404
8527
  function oldEvaluateFEELValues(validate, expressionLanguage, conditionChecker, form) {
8405
8528
  const evaluatedValidate = {
8406
8529
  ...validate
@@ -9862,5 +9985,5 @@ function createForm(options) {
9862
9985
  });
9863
9986
  }
9864
9987
 
9865
- export { ALLOW_ATTRIBUTE, Button, Checkbox, Checklist, ConditionChecker, DATETIME_SUBTYPES, DATETIME_SUBTYPES_LABELS, DATETIME_SUBTYPE_PATH, DATE_DISALLOW_PAST_PATH, DATE_LABEL_PATH, Datetime, Default, Description, DocumentPreview, DynamicList, Errors, ExpressionField, ExpressionFieldModule, ExpressionLanguageModule, ExpressionLoopPreventer, FeelExpressionLanguage, FeelersTemplating, FieldFactory, FilePicker, Form, FormComponent, FormContext, FormField, FormFieldRegistry, FormFields, FormLayouter, FormRenderContext, Group, Html, IFrame, Image, Importer, Label, LocalExpressionContext, MINUTES_IN_DAY, MarkdownRenderer, MarkdownRendererModule, Numberfield, OPTIONS_SOURCES, OPTIONS_SOURCES_DEFAULTS, OPTIONS_SOURCES_LABELS, OPTIONS_SOURCES_PATHS, OPTIONS_SOURCE_DEFAULT, PathRegistry, Radio, RenderModule, RepeatRenderManager, RepeatRenderModule, SANDBOX_ATTRIBUTE, SECURITY_ATTRIBUTES_DEFINITIONS, Select, Separator, Spacer, TEXT_VIEW_DEFAULT_TEXT, TIME_INTERVAL_PATH, TIME_LABEL_PATH, TIME_SERIALISINGFORMAT_LABELS, TIME_SERIALISING_FORMATS, TIME_SERIALISING_FORMAT_PATH, TIME_USE24H_PATH, Table, Taglist, Text, Textarea, Textfield, ViewerCommands, ViewerCommandsModule, buildExpressionContext, clone, createForm, createFormContainer, createInjector, escapeHTML, formFields, generateIdForType, generateIndexForType, getAncestryList, getOptionsSource, getSchemaVariables, getScrollContainer, hasEqualValue, iconsByType, isRequired, pathParse, pathsEqual, runExpressionEvaluation, runRecursively, sanitizeDateTimePickerValue, sanitizeHTML, sanitizeIFrameSource, sanitizeImageSource, sanitizeMultiSelectValue, sanitizeSingleSelectValue, schemaVersion, useExpressionEvaluation, useSingleLineTemplateEvaluation, useTemplateEvaluation, wrapCSSStyles, wrapObjectKeysWithUnderscores };
9988
+ export { ALLOW_ATTRIBUTE, Button, Checkbox, Checklist, ConditionChecker, DATETIME_SUBTYPES, DATETIME_SUBTYPES_LABELS, DATETIME_SUBTYPE_PATH, DATE_DISALLOW_PAST_PATH, DATE_LABEL_PATH, Datetime, Default, Description, DocumentPreview, DynamicList, Errors, ExpressionField, ExpressionFieldModule, ExpressionLanguageModule, ExpressionLoopPreventer, FeelExpressionLanguage, FeelersTemplating, FieldFactory, FilePicker, Form, FormComponent, FormContext, FormField, FormFieldRegistry, FormFields, FormLayouter, FormRenderContext, Group, Html, IFrame, Image, Importer, Label, LocalExpressionContext, MINUTES_IN_DAY, MarkdownRenderer, MarkdownRendererModule, Numberfield, OPTIONS_SOURCES, OPTIONS_SOURCES_DEFAULTS, OPTIONS_SOURCES_LABELS, OPTIONS_SOURCES_PATHS, OPTIONS_SOURCE_DEFAULT, PathRegistry, Radio, RenderModule, RepeatRenderManager, RepeatRenderModule, SANDBOX_ATTRIBUTE, SECURITY_ATTRIBUTES_DEFINITIONS, Select, Separator, Spacer, TEXT_VIEW_DEFAULT_TEXT, TIME_INTERVAL_PATH, TIME_LABEL_PATH, TIME_SERIALISINGFORMAT_LABELS, TIME_SERIALISING_FORMATS, TIME_SERIALISING_FORMAT_PATH, TIME_USE24H_PATH, Table, Taglist, Text, Textarea, Textfield, ViewerCommands, ViewerCommandsModule, buildExpressionContext, clone, createForm, createFormContainer, createInjector, escapeHTML, formFields, generateIdForType, generateIndexForType, getAncestryList, getOptionsSource, getSchemaVariables, getScrollContainer, hasEqualValue, iconsByType, isRequired, pathParse, pathsEqual, runExpressionEvaluation, runRecursively, runUnaryTestEvaluation, sanitizeDateTimePickerValue, sanitizeHTML, sanitizeIFrameSource, sanitizeImageSource, sanitizeMultiSelectValue, sanitizeSingleSelectValue, schemaVersion, useExpressionEvaluation, useSingleLineTemplateEvaluation, useTemplateEvaluation, wrapCSSStyles, wrapObjectKeysWithUnderscores };
9866
9989
  //# sourceMappingURL=index.es.js.map