@bpmn-io/feel-editor 1.12.0 → 2.0.0

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.js CHANGED
@@ -1,20 +1,18 @@
1
- 'use strict';
2
-
3
- var autocomplete = require('@codemirror/autocomplete');
4
- var commands = require('@codemirror/commands');
5
- var language$1 = require('@codemirror/language');
6
- var lint = require('@codemirror/lint');
7
- var state = require('@codemirror/state');
8
- var view = require('@codemirror/view');
9
- var feelLint = require('@bpmn-io/feel-lint');
10
- var highlight = require('@lezer/highlight');
11
- var langFeel = require('@bpmn-io/lang-feel');
12
- var minDom = require('min-dom');
13
- var feelBuiltins = require('@camunda/feel-builtins');
14
-
15
- var linter = [ lint.linter(feelLint.cmFeelLinter()) ];
16
-
17
- const baseTheme = view.EditorView.theme({
1
+ import { snippetCompletion, completeFromList, autocompletion, closeBrackets } from '@codemirror/autocomplete';
2
+ import { defaultKeymap } from '@codemirror/commands';
3
+ import { syntaxHighlighting, HighlightStyle, syntaxTree, bracketMatching, indentOnInput } from '@codemirror/language';
4
+ import { linter as linter$1, setDiagnosticsEffect } from '@codemirror/lint';
5
+ import { Facet, Compartment, EditorState } from '@codemirror/state';
6
+ import { EditorView, tooltips, keymap, placeholder } from '@codemirror/view';
7
+ import { cmFeelLinter } from '@bpmn-io/feel-lint';
8
+ import { tags } from '@lezer/highlight';
9
+ import { keywordCompletions, snippets, feel } from '@bpmn-io/lang-feel';
10
+ import { domify } from 'min-dom';
11
+ import { camundaBuiltins } from '@camunda/feel-builtins';
12
+
13
+ var linter = [ linter$1(cmFeelLinter()) ];
14
+
15
+ const baseTheme = EditorView.theme({
18
16
  '& .cm-content': {
19
17
  padding: '0px',
20
18
  },
@@ -53,7 +51,7 @@ const baseTheme = view.EditorView.theme({
53
51
  }
54
52
  });
55
53
 
56
- const highlightTheme = view.EditorView.baseTheme({
54
+ const highlightTheme = EditorView.baseTheme({
57
55
  '& .variableName': {
58
56
  color: '#10f'
59
57
  },
@@ -75,17 +73,17 @@ const highlightTheme = view.EditorView.baseTheme({
75
73
  }
76
74
  });
77
75
 
78
- const syntaxClasses = language$1.syntaxHighlighting(
79
- language$1.HighlightStyle.define([
80
- { tag: highlight.tags.variableName, class: 'variableName' },
81
- { tag: highlight.tags.name, class: 'variableName' },
82
- { tag: highlight.tags.number, class: 'number' },
83
- { tag: highlight.tags.string, class: 'string' },
84
- { tag: highlight.tags.bool, class: 'bool' },
85
- { tag: highlight.tags.function(highlight.tags.variableName), class: 'function' },
86
- { tag: highlight.tags.function(highlight.tags.special(highlight.tags.variableName)), class: 'function' },
87
- { tag: highlight.tags.controlKeyword, class: 'control' },
88
- { tag: highlight.tags.operatorKeyword, class: 'control' }
76
+ const syntaxClasses = syntaxHighlighting(
77
+ HighlightStyle.define([
78
+ { tag: tags.variableName, class: 'variableName' },
79
+ { tag: tags.name, class: 'variableName' },
80
+ { tag: tags.number, class: 'number' },
81
+ { tag: tags.string, class: 'string' },
82
+ { tag: tags.bool, class: 'bool' },
83
+ { tag: tags.function(tags.variableName), class: 'function' },
84
+ { tag: tags.function(tags.special(tags.variableName)), class: 'function' },
85
+ { tag: tags.controlKeyword, class: 'control' },
86
+ { tag: tags.operatorKeyword, class: 'control' }
89
87
  ])
90
88
  );
91
89
 
@@ -147,10 +145,10 @@ function pathExpressionCompletion({ variables }) {
147
145
 
148
146
  return (context) => {
149
147
 
150
- const nodeBefore = language$1.syntaxTree(context.state).resolve(context.pos, -1);
148
+ const nodeBefore = syntaxTree(context.state).resolve(context.pos, -1);
151
149
 
152
150
  if (!isPathExpression(nodeBefore)) {
153
- return;
151
+ return null;
154
152
  }
155
153
 
156
154
  const expression = findPathExpression(nodeBefore);
@@ -171,26 +169,27 @@ function pathExpressionCompletion({ variables }) {
171
169
  // only suggest if variable type matches
172
170
  if (
173
171
  childVar.isList !== 'optional' &&
174
- !!childVar.isList !== path[i].isList
172
+ !!childVar.isList !== path[i].isList
175
173
  ) {
176
- return;
174
+ return null;
177
175
  }
178
176
 
179
177
  options = childVar.entries;
180
178
  }
181
179
 
182
- if (!options) return;
180
+ if (!options) return null;
183
181
 
184
- options = options.map(v => ({
185
- label: v.name,
186
- type: 'variable',
187
- info: v.info,
188
- detail: v.detail
189
- }));
182
+ const completionOptions = options.map(option => (
183
+ {
184
+ label: option.name,
185
+ type: 'variable',
186
+ info: option.info,
187
+ detail: option.detail
188
+ }));
190
189
 
191
190
  const result = {
192
191
  from: from,
193
- options: options
192
+ options: completionOptions
194
193
  };
195
194
 
196
195
  return result;
@@ -278,7 +277,7 @@ function variableCompletion({ variables = [], builtins = [] }) {
278
277
  } = context;
279
278
 
280
279
  // in most cases, use what is typed before the cursor
281
- const nodeBefore = language$1.syntaxTree(state).resolve(pos, -1);
280
+ const nodeBefore = syntaxTree(state).resolve(pos, -1);
282
281
 
283
282
  if (isEmpty(nodeBefore, pos)) {
284
283
  return context.explicit ? {
@@ -314,8 +313,8 @@ function getVariableSuggestions(variables, builtins) {
314
313
 
315
314
  /**
316
315
  * @param {import('..').Variable} variable
317
- * @param {number} boost
318
-
316
+ * @param {number} [boost]
317
+ *
319
318
  * @returns {import('@codemirror/autocomplete').Completion}
320
319
  */
321
320
  function createVariableSuggestion(variable, boost) {
@@ -358,7 +357,7 @@ function createFunctionVariable(variable, boost) {
358
357
  )).join(', ');
359
358
  const label = `${name}(${paramsSignature})`;
360
359
 
361
- return autocomplete.snippetCompletion(template, {
360
+ return snippetCompletion(template, {
362
361
  label,
363
362
  type: 'function',
364
363
  info,
@@ -385,8 +384,8 @@ function completions({ variables = [], builtins = [] }) {
385
384
  return [
386
385
  pathExpressionCompletion({ variables }),
387
386
  variableCompletion({ variables, builtins }),
388
- langFeel.snippets,
389
- ...langFeel.keywordCompletions
387
+ completeFromList(snippets),
388
+ ...keywordCompletions
390
389
  ];
391
390
  }
392
391
 
@@ -409,7 +408,7 @@ function completions({ variables = [], builtins = [] }) {
409
408
  * @return { import('@codemirror/language').LanguageSupport }
410
409
  */
411
410
  function language(options) {
412
- return langFeel.feel(options);
411
+ return feel(options);
413
412
  }
414
413
 
415
414
  /**
@@ -434,32 +433,32 @@ function createContext(variables) {
434
433
  /**
435
434
  * @type {Facet<Variable[]>}
436
435
  */
437
- const builtinsFacet = state.Facet.define();
436
+ const builtinsFacet = Facet.define();
438
437
 
439
438
  /**
440
439
  * @type {Facet<Variable[]>}
441
440
  */
442
- const variablesFacet = state.Facet.define();
441
+ const variablesFacet = Facet.define();
443
442
 
444
443
  /**
445
444
  * @type {Facet<Dialect>}
446
445
  */
447
- const dialectFacet = state.Facet.define();
446
+ const dialectFacet = Facet.define();
448
447
 
449
448
  /**
450
449
  * @type {Facet<ParserDialect>}
451
450
  */
452
- const parserDialectFacet = state.Facet.define();
451
+ const parserDialectFacet = Facet.define();
453
452
 
454
453
  /**
455
454
  * @typedef {object} Variable
456
455
  * @property {string} name name or key of the variable
457
- * @property {string} [info] short information about the variable, e.g. type
456
+ * @property {string | (() => HTMLElement)} [info] short information about the variable, e.g. type
458
457
  * @property {string} [detail] longer description of the variable content
459
- * @property {boolean} [isList] whether the variable is a list
460
- * @property {Array<Variable>} [schema] array of child variables if the variable is a context or list
458
+ * @property {boolean|'optional'} [isList] whether the variable is a list
459
+ * @property {Array<Variable>} [entries] array of child variables if the variable is a context or list
461
460
  * @property {'function'|'variable'} [type] type of the variable
462
- * @property {Array<{name: string, type: string}>} [params] function parameters
461
+ * @property {Array<{name: string, type?: string}>} [params] function parameters
463
462
  */
464
463
 
465
464
  /**
@@ -523,9 +522,9 @@ function get(state) {
523
522
  };
524
523
  }
525
524
 
526
- const domifiedBuiltins = feelBuiltins.camundaBuiltins.map(builtin => ({
525
+ const domifiedBuiltins = camundaBuiltins.map(builtin => ({
527
526
  ...builtin,
528
- info: () => minDom.domify(builtin.info),
527
+ info: () => domify(builtin.info),
529
528
  }));
530
529
 
531
530
  /**
@@ -537,8 +536,8 @@ const domifiedBuiltins = feelBuiltins.camundaBuiltins.map(builtin => ({
537
536
  * @typedef { import('./language').ParserDialect } ParserDialect
538
537
  */
539
538
 
540
- const coreConf = new state.Compartment();
541
- const placeholderConf = new state.Compartment();
539
+ const coreConf = new Compartment();
540
+ const placeholderConf = new Compartment();
542
541
 
543
542
 
544
543
  /**
@@ -551,12 +550,14 @@ const placeholderConf = new state.Compartment();
551
550
  * @param {ParserDialect} [config.parserDialect]
552
551
  * @param {DOMNode|String} [config.tooltipContainer]
553
552
  * @param {Function} [config.onChange]
554
- * @param {Function} [config.onKeyDown]
553
+ * @param {(event: KeyboardEvent, view: import('@codemirror/view').EditorView) => boolean | void} [config.onKeyDown]
555
554
  * @param {Function} [config.onLint]
556
555
  * @param {Boolean} [config.readOnly]
557
556
  * @param {String} [config.value]
558
557
  * @param {Variable[]} [config.variables]
559
558
  * @param {Variable[]} [config.builtins]
559
+ * @param {Object} [config.contentAttributes]
560
+ * @param {String} [config.placeholder]
560
561
  */
561
562
  function FeelEditor({
562
563
  extensions: editorExtensions = [],
@@ -568,23 +569,23 @@ function FeelEditor({
568
569
  onChange = () => {},
569
570
  onKeyDown = () => {},
570
571
  onLint = () => {},
571
- placeholder = '',
572
+ placeholder: placeholder$1 = '',
572
573
  readOnly = false,
573
574
  value = '',
574
575
  builtins = domifiedBuiltins,
575
576
  variables = []
576
577
  }) {
577
578
 
578
- const changeHandler = view.EditorView.updateListener.of((update) => {
579
+ const changeHandler = EditorView.updateListener.of((update) => {
579
580
  if (update.docChanged) {
580
581
  onChange(update.state.doc.toString());
581
582
  }
582
583
  });
583
584
 
584
- const lintHandler = view.EditorView.updateListener.of((update) => {
585
+ const lintHandler = EditorView.updateListener.of((update) => {
585
586
  const diagnosticEffects = update.transactions
586
587
  .flatMap(t => t.effects)
587
- .filter(effect => effect.is(lint.setDiagnosticsEffect));
588
+ .filter(effect => effect.is(setDiagnosticsEffect));
588
589
 
589
590
  if (!diagnosticEffects.length) {
590
591
  return;
@@ -595,53 +596,53 @@ function FeelEditor({
595
596
  onLint(messages);
596
597
  });
597
598
 
598
- const keyHandler = view.EditorView.domEventHandlers(
599
+ const keyHandler = EditorView.domEventHandlers(
599
600
  {
600
601
  keydown: onKeyDown
601
602
  }
602
603
  );
603
604
 
604
605
  if (typeof tooltipContainer === 'string') {
605
- tooltipContainer = document.querySelector(tooltipContainer);
606
+ tooltipContainer = /** @type {HTMLElement} */ (document.querySelector(tooltipContainer));
606
607
  }
607
608
 
608
- const tooltipLayout = tooltipContainer ? view.tooltips({
609
+ const tooltipLayout = tooltipContainer ? tooltips({
609
610
  tooltipSpace: function() {
610
- return tooltipContainer.getBoundingClientRect();
611
+ return /** @type {HTMLElement} */ (tooltipContainer).getBoundingClientRect();
611
612
  }
612
613
  }) : [];
613
614
 
614
615
  const extensions = [
615
- autocomplete.autocompletion(),
616
+ autocompletion(),
616
617
  coreConf.of(configure({
617
618
  dialect,
618
619
  builtins,
619
620
  variables,
620
621
  parserDialect
621
622
  })),
622
- language$1.bracketMatching(),
623
- language$1.indentOnInput(),
624
- autocomplete.closeBrackets(),
625
- view.EditorView.contentAttributes.of(contentAttributes),
623
+ bracketMatching(),
624
+ indentOnInput(),
625
+ closeBrackets(),
626
+ EditorView.contentAttributes.of(contentAttributes),
626
627
  changeHandler,
627
628
  keyHandler,
628
- view.keymap.of([
629
- ...commands.defaultKeymap,
629
+ keymap.of([
630
+ ...defaultKeymap,
630
631
  ]),
631
632
  linter,
632
633
  lintHandler,
633
634
  tooltipLayout,
634
- placeholderConf.of(view.placeholder(placeholder)),
635
+ placeholderConf.of(placeholder(placeholder$1)),
635
636
  theme,
636
637
  ...editorExtensions
637
638
  ];
638
639
 
639
640
  if (readOnly) {
640
- extensions.push(view.EditorView.editable.of(false));
641
+ extensions.push(EditorView.editable.of(false));
641
642
  }
642
643
 
643
- this._cmEditor = new view.EditorView({
644
- state: state.EditorState.create({
644
+ this._cmEditor = new EditorView({
645
+ state: EditorState.create({
645
646
  doc: value,
646
647
  extensions
647
648
  }),
@@ -687,8 +688,7 @@ FeelEditor.prototype.focus = function(position) {
687
688
  * Returns the current selection ranges. If no text is selected, a single
688
689
  * range with the start and end index at the cursor position will be returned.
689
690
  *
690
- * @returns {Object} selection
691
- * @returns {Array} selection.ranges
691
+ * @returns {import('@codemirror/state').EditorSelection} selection - Selection object with ranges array
692
692
  */
693
693
  FeelEditor.prototype.getSelection = function() {
694
694
  return this._cmEditor.state.selection;
@@ -718,10 +718,11 @@ FeelEditor.prototype.setVariables = function(variables) {
718
718
  *
719
719
  * @param {string} placeholder
720
720
  */
721
- FeelEditor.prototype.setPlaceholder = function(placeholder) {
721
+ FeelEditor.prototype.setPlaceholder = function(placeholder$1) {
722
722
  this._cmEditor.dispatch({
723
- effects: placeholderConf.reconfigure(view.placeholder(placeholder))
723
+ effects: placeholderConf.reconfigure(placeholder(placeholder$1))
724
724
  });
725
725
  };
726
726
 
727
- module.exports = FeelEditor;
727
+ export { FeelEditor as default };
728
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../src/lint/index.js","../src/theme/theme.js","../src/theme/index.js","../src/autocompletion/util.js","../src/autocompletion/pathExpression.js","../src/autocompletion/variable.js","../src/autocompletion/index.js","../src/language/index.js","../src/core/facets.js","../src/core/index.js","../src/builtins/index.js","../src/index.js"],"sourcesContent":["import { cmFeelLinter } from '@bpmn-io/feel-lint';\nimport { linter } from '@codemirror/lint';\n\nexport default [ linter(cmFeelLinter()) ];","import { HighlightStyle, syntaxHighlighting } from '@codemirror/language';\nimport { EditorView } from '@codemirror/view';\nimport { tags as t } from '@lezer/highlight';\n\nexport const baseTheme = EditorView.theme({\n '& .cm-content': {\n padding: '0px',\n },\n '& .cm-line': {\n padding: '0px',\n },\n '&.cm-editor.cm-focused': {\n outline: 'none',\n },\n '& .cm-completionInfo': {\n whiteSpace: 'pre-wrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis'\n },\n '&.cm-editor': {\n height: '100%',\n },\n\n // Don't wrap whitespace for custom HTML\n '& .cm-completionInfo > *': {\n whiteSpace: 'normal'\n },\n '& .cm-completionInfo ul': {\n margin: 0,\n paddingLeft: '15px'\n },\n '& .cm-completionInfo pre': {\n marginBottom: 0,\n whiteSpace: 'pre-wrap'\n },\n '& .cm-completionInfo p': {\n marginTop: 0,\n },\n '& .cm-completionInfo p:not(:last-of-type)': {\n marginBottom: 0,\n }\n});\n\nexport const highlightTheme = EditorView.baseTheme({\n '& .variableName': {\n color: '#10f'\n },\n '& .number': {\n color: '#164'\n },\n '& .string': {\n color: '#a11'\n },\n '& .bool': {\n color: '#219'\n },\n '& .function': {\n color: '#aa3731',\n fontWeight: 'bold'\n },\n '& .control': {\n color: '#708'\n }\n});\n\nexport const syntaxClasses = syntaxHighlighting(\n HighlightStyle.define([\n { tag: t.variableName, class: 'variableName' },\n { tag: t.name, class: 'variableName' },\n { tag: t.number, class: 'number' },\n { tag: t.string, class: 'string' },\n { tag: t.bool, class: 'bool' },\n { tag: t.function(t.variableName), class: 'function' },\n { tag: t.function(t.special(t.variableName)), class: 'function' },\n { tag: t.controlKeyword, class: 'control' },\n { tag: t.operatorKeyword, class: 'control' }\n ])\n);","import { baseTheme, highlightTheme, syntaxClasses } from './theme.js';\n\nexport default [ baseTheme, highlightTheme, syntaxClasses ];","// helpers ///////////////////////////////\n\nfunction _isEmpty(node) {\n return node && node.from === node.to;\n}\n\n/**\n * @param {any} node\n * @param {number} pos\n *\n * @return {boolean}\n */\nexport function isEmpty(node, pos) {\n\n // For the special case of empty nodes, we need to check the current node\n // as well. The previous node could be part of another token, e.g.\n // when typing functions \"abs(\".\n const nextNode = node.nextSibling;\n\n return _isEmpty(node) || (\n nextNode && nextNode.from === pos && _isEmpty(nextNode)\n );\n}\n\nexport function isVariableName(node) {\n return node && node.parent && node.parent.name === 'VariableName';\n}\n\nexport function isPathExpression(node) {\n if (!node) {\n return false;\n }\n\n if (node.name === 'PathExpression') {\n return true;\n }\n\n return isPathExpression(node.parent);\n}\n","import { syntaxTree } from '@codemirror/language';\nimport { isPathExpression } from './util.js';\n\n/**\n * @typedef { import('../core').Variable } Variable\n * @typedef { import('@codemirror/autocomplete').CompletionSource } CompletionSource\n */\n\n/**\n * @param { {\n * variables?: Variable[],\n * } } options\n *\n * @return { CompletionSource }\n */\nexport function pathExpressionCompletion({ variables }) {\n\n return (context) => {\n\n const nodeBefore = syntaxTree(context.state).resolve(context.pos, -1);\n\n if (!isPathExpression(nodeBefore)) {\n return null;\n }\n\n const expression = findPathExpression(nodeBefore);\n\n // if the cursor is directly after the `.`, variable starts at the cursor position\n const from = nodeBefore === expression ? context.pos : nodeBefore.from;\n\n const path = getPath(expression, context);\n\n let options = variables;\n for (var i = 0; i < path.length - 1; i++) {\n var childVar = options.find(val => val.name === path[i].name);\n\n if (!childVar) {\n return null;\n }\n\n // only suggest if variable type matches\n if (\n childVar.isList !== 'optional' &&\n !!childVar.isList !== path[i].isList\n ) {\n return null;\n }\n\n options = childVar.entries;\n }\n\n if (!options) return null;\n\n const completionOptions = options.map(option => (\n {\n label: option.name,\n type: 'variable',\n info: option.info,\n detail: option.detail\n }));\n\n const result = {\n from: from,\n options: completionOptions\n };\n\n return result;\n };\n}\n\n\nfunction findPathExpression(node) {\n while (node) {\n if (node.name === 'PathExpression') {\n return node;\n }\n node = node.parent;\n }\n}\n\n// parses the path expression into a list of variable names with type information\n// e.g. foo[0].bar => [ { name: 'foo', isList: true }, { name: 'bar', isList: false } ]\nfunction getPath(node, context) {\n let path = [];\n\n for (let child = node.firstChild; child; child = child.nextSibling) {\n if (child.name === 'PathExpression') {\n path.push(...getPath(child, context));\n } else if (child.name === 'FilterExpression') {\n path.push(...getFilter(child, context));\n }\n else {\n path.push({\n name: getNodeContent(child, context),\n isList: false\n });\n }\n }\n return path;\n}\n\nfunction getFilter(node, context) {\n const list = node.firstChild;\n\n if (list.name === 'PathExpression') {\n const path = getPath(list, context);\n const last = path[path.length - 1];\n last.isList = true;\n\n return path;\n }\n\n return [ {\n name: getNodeContent(list, context),\n isList: true\n } ];\n}\n\nfunction getNodeContent(node, context) {\n return context.state.sliceDoc(node.from, node.to);\n}","import { syntaxTree } from '@codemirror/language';\nimport { snippetCompletion } from '@codemirror/autocomplete';\nimport { isEmpty, isPathExpression, isVariableName } from './util.js';\n\n/**\n * @typedef { import('../core').Variable } Variable\n * @typedef { import('@codemirror/autocomplete').CompletionSource } CompletionSource\n */\n\n/**\n * @param { {\n * variables?: Variable[],\n * builtins?: Variable[]\n * } } options\n *\n * @return { CompletionSource }\n */\nexport function variableCompletion({ variables = [], builtins = [] }) {\n\n const options = getVariableSuggestions(variables, builtins);\n\n if (!options.length) {\n return (context) => null;\n }\n\n return (context) => {\n\n const {\n pos,\n state\n } = context;\n\n // in most cases, use what is typed before the cursor\n const nodeBefore = syntaxTree(state).resolve(pos, -1);\n\n if (isEmpty(nodeBefore, pos)) {\n return context.explicit ? {\n from: pos,\n options\n } : null;\n }\n\n // only auto-complete variables\n if (!isVariableName(nodeBefore) || isPathExpression(nodeBefore)) {\n return null;\n }\n\n return {\n from: nodeBefore.from,\n options\n };\n };\n}\n\n/**\n * @param { Variable[] } variables\n * @param { Variable[] } builtins\n *\n * @returns {import('@codemirror/autocomplete').Completion[]}\n */\nfunction getVariableSuggestions(variables, builtins) {\n return [].concat(\n variables.map(v => createVariableSuggestion(v)),\n builtins.map(b => createVariableSuggestion(b))\n );\n}\n\n/**\n * @param {import('..').Variable} variable\n * @param {number} [boost]\n *\n * @returns {import('@codemirror/autocomplete').Completion}\n */\nfunction createVariableSuggestion(variable, boost) {\n if (variable.type === 'function') {\n return createFunctionVariable(variable, boost);\n }\n\n return {\n label: variable.name,\n type: 'variable',\n info: variable.info,\n detail: variable.detail,\n boost\n };\n}\n\n/**\n * @param {import('..').Variable} variable\n * @param {number} boost\n *\n * @returns {import('@codemirror/autocomplete').Completion}\n */\nfunction createFunctionVariable(variable, boost) {\n const {\n name,\n info,\n detail,\n params = []\n } = variable;\n\n const paramsWithNames = params.map(({ name, type }, index) => ({\n name: name || `param ${index + 1}`,\n type\n }));\n\n const template = `${name}(${paramsWithNames.map(p => '${' + p.name + '}').join(', ')})`;\n\n const paramsSignature = paramsWithNames.map(({ name, type }) => (\n type ? `${name}: ${type}` : name\n )).join(', ');\n const label = `${name}(${paramsSignature})`;\n\n return snippetCompletion(template, {\n label,\n type: 'function',\n info,\n detail,\n boost\n });\n}\n","import { snippets, keywordCompletions } from '@bpmn-io/lang-feel';\nimport { completeFromList } from '@codemirror/autocomplete';\n\nimport { pathExpressionCompletion } from './pathExpression.js';\nimport { variableCompletion } from './variable.js';\n\n/**\n * @typedef { import('../core').Variable } Variable\n * @typedef { import('@codemirror/autocomplete').CompletionSource } CompletionSource\n */\n\n/**\n * @param { {\n * variables?: Variable[],\n * builtins?: Variable[]\n * } } options\n *\n * @return { CompletionSource[] }\n */\nexport function completions({ variables = [], builtins = [] }) {\n\n return [\n pathExpressionCompletion({ variables }),\n variableCompletion({ variables, builtins }),\n completeFromList(snippets),\n ...keywordCompletions\n ];\n}","import { feel } from '@bpmn-io/lang-feel';\n\n/**\n * @typedef { 'expression' | 'unaryTests' } Dialect\n */\n\n/**\n * @typedef { 'camunda' | undefined } ParserDialect\n */\n\n/**\n * @param { {\n * dialect?: Dialect,\n * parserDialect?: ParserDialect,\n * context?: Record<string, any>,\n * completions?: import('@codemirror/autocomplete').CompletionSource[]\n * } } options\n *\n * @return { import('@codemirror/language').LanguageSupport }\n */\nexport function language(options) {\n return feel(options);\n}\n\n/**\n * @param { import('../core').Variable[] } variables\n *\n * @return {Record<string, any>}\n */\nexport function createContext(variables) {\n return variables.slice().reverse().reduce((context, builtin) => {\n context[builtin.name] = () => {};\n\n return context;\n }, {});\n}","import { Facet } from '@codemirror/state';\n\n/**\n * @typedef { import('../language').Dialect } Dialect\n * @typedef { import('../language').ParserDialect } ParserDialect\n * @typedef { import('..').Variable } Variable\n */\n\n/**\n * @type {Facet<Variable[]>}\n */\nexport const builtinsFacet = Facet.define();\n\n/**\n * @type {Facet<Variable[]>}\n */\nexport const variablesFacet = Facet.define();\n\n/**\n * @type {Facet<Dialect>}\n */\nexport const dialectFacet = Facet.define();\n\n/**\n * @type {Facet<ParserDialect>}\n */\nexport const parserDialectFacet = Facet.define();\n\n","import { completions as feelCompletions } from '../autocompletion/index.js';\n\nimport { createContext, language } from '../language/index.js';\n\nimport {\n variablesFacet,\n builtinsFacet,\n parserDialectFacet,\n dialectFacet\n} from './facets.js';\n\n\n/**\n * @typedef {object} Variable\n * @property {string} name name or key of the variable\n * @property {string | (() => HTMLElement)} [info] short information about the variable, e.g. type\n * @property {string} [detail] longer description of the variable content\n * @property {boolean|'optional'} [isList] whether the variable is a list\n * @property {Array<Variable>} [entries] array of child variables if the variable is a context or list\n * @property {'function'|'variable'} [type] type of the variable\n * @property {Array<{name: string, type?: string}>} [params] function parameters\n */\n\n/**\n * @typedef { {\n * dialect?: import('../language').Dialect,\n * parserDialect?: import('../language').ParserDialect,\n * variables?: Variable[],\n * builtins?: Variable[]\n * } } CoreConfig\n *\n * @typedef { import('@codemirror/autocomplete').CompletionSource } CompletionSource\n * @typedef { import('@codemirror/state').Extension } Extension\n */\n\n/**\n * @param { CoreConfig & { completions?: CompletionSource[] } } config\n *\n * @return { Extension }\n */\nexport function configure({\n dialect = 'expression',\n parserDialect,\n variables = [],\n builtins = [],\n completions = feelCompletions({ builtins, variables })\n}) {\n\n const context = createContext([ ...variables, ...builtins ]);\n\n return [\n dialectFacet.of(dialect),\n builtinsFacet.of(builtins),\n variablesFacet.of(variables),\n parserDialectFacet.of(parserDialect),\n language({\n dialect,\n parserDialect,\n context,\n completions\n })\n ];\n}\n\n/**\n * @param {import('@codemirror/state').EditorState } state\n *\n * @return { CoreConfig }\n */\nexport function get(state) {\n\n const builtins = state.facet(builtinsFacet)[0];\n const variables = state.facet(variablesFacet)[0];\n const dialect = state.facet(dialectFacet)[0];\n const parserDialect = state.facet(parserDialectFacet)[0];\n\n return {\n builtins,\n variables,\n dialect,\n parserDialect\n };\n}","import { domify } from 'min-dom';\nimport { camundaBuiltins } from '@camunda/feel-builtins';\n\nexport const domifiedBuiltins = camundaBuiltins.map(builtin => ({\n ...builtin,\n info: () => domify(builtin.info),\n}));","import { autocompletion, closeBrackets } from '@codemirror/autocomplete';\nimport { defaultKeymap } from '@codemirror/commands';\nimport { bracketMatching, indentOnInput } from '@codemirror/language';\nimport { setDiagnosticsEffect } from '@codemirror/lint';\nimport { Compartment, EditorState } from '@codemirror/state';\nimport { EditorView, keymap, placeholder as placeholderExt, tooltips } from '@codemirror/view';\n\nimport linter from './lint/index.js';\nimport theme from './theme/index.js';\n\nimport * as Core from './core/index.js';\n\nimport { domifiedBuiltins } from './builtins/index.js';\n\n/**\n * @typedef { import('./core').Variable } Variable\n */\n\n/**\n * @typedef { import('./language').Dialect } Dialect\n * @typedef { import('./language').ParserDialect } ParserDialect\n */\n\nconst coreConf = new Compartment();\nconst placeholderConf = new Compartment();\n\n\n/**\n * Creates a FEEL editor in the supplied container\n *\n * @param {Object} config\n * @param {DOMNode} config.container\n * @param {Extension[]} [config.extensions]\n * @param {Dialect} [config.dialect='expression']\n * @param {ParserDialect} [config.parserDialect]\n * @param {DOMNode|String} [config.tooltipContainer]\n * @param {Function} [config.onChange]\n * @param {(event: KeyboardEvent, view: import('@codemirror/view').EditorView) => boolean | void} [config.onKeyDown]\n * @param {Function} [config.onLint]\n * @param {Boolean} [config.readOnly]\n * @param {String} [config.value]\n * @param {Variable[]} [config.variables]\n * @param {Variable[]} [config.builtins]\n * @param {Object} [config.contentAttributes]\n * @param {String} [config.placeholder]\n */\nexport default function FeelEditor({\n extensions: editorExtensions = [],\n dialect = 'expression',\n parserDialect,\n container,\n contentAttributes = {},\n tooltipContainer,\n onChange = () => {},\n onKeyDown = () => {},\n onLint = () => {},\n placeholder = '',\n readOnly = false,\n value = '',\n builtins = domifiedBuiltins,\n variables = []\n}) {\n\n const changeHandler = EditorView.updateListener.of((update) => {\n if (update.docChanged) {\n onChange(update.state.doc.toString());\n }\n });\n\n const lintHandler = EditorView.updateListener.of((update) => {\n const diagnosticEffects = update.transactions\n .flatMap(t => t.effects)\n .filter(effect => effect.is(setDiagnosticsEffect));\n\n if (!diagnosticEffects.length) {\n return;\n }\n\n const messages = diagnosticEffects.flatMap(effect => effect.value);\n\n onLint(messages);\n });\n\n const keyHandler = EditorView.domEventHandlers(\n {\n keydown: onKeyDown\n }\n );\n\n if (typeof tooltipContainer === 'string') {\n tooltipContainer = /** @type {HTMLElement} */ (document.querySelector(tooltipContainer));\n }\n\n const tooltipLayout = tooltipContainer ? tooltips({\n tooltipSpace: function() {\n return /** @type {HTMLElement} */ (tooltipContainer).getBoundingClientRect();\n }\n }) : [];\n\n const extensions = [\n autocompletion(),\n coreConf.of(Core.configure({\n dialect,\n builtins,\n variables,\n parserDialect\n })),\n bracketMatching(),\n indentOnInput(),\n closeBrackets(),\n EditorView.contentAttributes.of(contentAttributes),\n changeHandler,\n keyHandler,\n keymap.of([\n ...defaultKeymap,\n ]),\n linter,\n lintHandler,\n tooltipLayout,\n placeholderConf.of(placeholderExt(placeholder)),\n theme,\n ...editorExtensions\n ];\n\n if (readOnly) {\n extensions.push(EditorView.editable.of(false));\n }\n\n this._cmEditor = new EditorView({\n state: EditorState.create({\n doc: value,\n extensions\n }),\n parent: container\n });\n\n return this;\n}\n\n/**\n * Replaces the content of the Editor\n *\n * @param {String} value\n */\nFeelEditor.prototype.setValue = function(value) {\n this._cmEditor.dispatch({\n changes: {\n from: 0,\n to: this._cmEditor.state.doc.length,\n insert: value,\n }\n });\n};\n\n/**\n * Sets the focus in the editor.\n */\nFeelEditor.prototype.focus = function(position) {\n const cmEditor = this._cmEditor;\n\n // the Codemirror `focus` method always calls `focus` with `preventScroll`,\n // so we have to focus + scroll manually\n cmEditor.contentDOM.focus();\n cmEditor.focus();\n\n if (typeof position === 'number') {\n const end = cmEditor.state.doc.length;\n cmEditor.dispatch({ selection: { anchor: position <= end ? position : end } });\n }\n};\n\n/**\n * Returns the current selection ranges. If no text is selected, a single\n * range with the start and end index at the cursor position will be returned.\n *\n * @returns {import('@codemirror/state').EditorSelection} selection - Selection object with ranges array\n */\nFeelEditor.prototype.getSelection = function() {\n return this._cmEditor.state.selection;\n};\n\n/**\n * Set variables to be used for autocompletion.\n *\n * @param {Variable[]} variables\n */\nFeelEditor.prototype.setVariables = function(variables) {\n\n const config = Core.get(this._cmEditor.state);\n\n this._cmEditor.dispatch({\n effects: [\n coreConf.reconfigure(Core.configure({\n ...config,\n variables\n }))\n ]\n });\n};\n\n/**\n * Update placeholder text.\n *\n * @param {string} placeholder\n */\nFeelEditor.prototype.setPlaceholder = function(placeholder) {\n this._cmEditor.dispatch({\n effects: placeholderConf.reconfigure(placeholderExt(placeholder))\n });\n};"],"names":["linter","t","completions","feelCompletions","placeholder","Core.configure","placeholderExt","Core.get"],"mappings":"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"}
package/package.json CHANGED
@@ -1,18 +1,23 @@
1
1
  {
2
2
  "name": "@bpmn-io/feel-editor",
3
- "version": "1.12.0",
3
+ "version": "2.0.0",
4
4
  "description": "Editor for FEEL expressions.",
5
- "files": [
6
- "dist"
7
- ],
8
- "main": "dist/index.js",
9
- "module": "dist/index.es.js",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "source": "./src/index.js",
8
+ "exports": {
9
+ ".": "./dist/index.js",
10
+ "./package.json": "./package.json"
11
+ },
10
12
  "scripts": {
11
- "all": "run-s lint test build",
12
- "test": "karma start",
13
+ "all": "run-s lint check-types test build",
14
+ "test": "karma start karma.conf.cjs",
13
15
  "build": "rollup -c --bundleConfigAsCjs",
14
16
  "build:watch": "npm run build -- -w",
15
17
  "lint": "eslint .",
18
+ "check-types": "run-s check-types:*",
19
+ "check-types:src": "tsc",
20
+ "check-types:test": "tsc -p test",
16
21
  "start": "cross-env SINGLE_START=true npm run dev",
17
22
  "start:camunda": "cross-env SINGLE_START=camunda npm run dev",
18
23
  "dev": "npm test -- --auto-watch --no-single-run",
@@ -26,8 +31,11 @@
26
31
  "access": "public"
27
32
  },
28
33
  "engines": {
29
- "node": ">= 16"
34
+ "node": ">= 20"
30
35
  },
36
+ "files": [
37
+ "dist"
38
+ ],
31
39
  "keywords": [
32
40
  "bpmn-io",
33
41
  "feel",
@@ -45,16 +53,16 @@
45
53
  ],
46
54
  "license": "MIT",
47
55
  "dependencies": {
48
- "@bpmn-io/feel-lint": "^2.1.0",
56
+ "@bpmn-io/feel-lint": "^3.0.0",
57
+ "@bpmn-io/lang-feel": "^3.0.0",
49
58
  "@camunda/feel-builtins": "^0.2.0",
50
- "@codemirror/autocomplete": "^6.16.2",
51
- "@codemirror/commands": "^6.8.0",
52
- "@codemirror/language": "^6.10.2",
53
- "@codemirror/lint": "^6.8.4",
54
- "@codemirror/state": "^6.5.1",
55
- "@codemirror/view": "^6.36.2",
56
- "@lezer/highlight": "^1.2.1",
57
- "@bpmn-io/lang-feel": "^2.4.0",
59
+ "@codemirror/autocomplete": "^6.20.0",
60
+ "@codemirror/commands": "^6.10.0",
61
+ "@codemirror/language": "^6.11.3",
62
+ "@codemirror/lint": "^6.9.2",
63
+ "@codemirror/state": "^6.5.2",
64
+ "@codemirror/view": "^6.38.8",
65
+ "@lezer/highlight": "^1.2.3",
58
66
  "min-dom": "^4.2.1"
59
67
  },
60
68
  "devDependencies": {
@@ -63,12 +71,16 @@
63
71
  "@rollup/plugin-json": "^6.1.0",
64
72
  "@testing-library/dom": "^10.4.0",
65
73
  "@testing-library/user-event": "^14.6.1",
74
+ "@types/chai": "^5.2.3",
75
+ "@types/mocha": "^10.0.10",
76
+ "@types/sinon": "^21.0.0",
77
+ "@types/sinon-chai": "^4.0.0",
66
78
  "babel-loader": "^9.2.1",
67
79
  "babel-plugin-istanbul": "^7.0.0",
68
- "chai": "^4.5.0",
80
+ "chai": "^6.2.1",
69
81
  "cross-env": "^7.0.3",
70
- "eslint": "^8.57.0",
71
- "eslint-plugin-bpmn-io": "^1.0.0",
82
+ "eslint": "^9.39.1",
83
+ "eslint-plugin-bpmn-io": "^2.2.0",
72
84
  "karma": "^6.4.4",
73
85
  "karma-chrome-launcher": "^3.2.0",
74
86
  "karma-coverage": "^2.2.1",
@@ -76,15 +88,15 @@
76
88
  "karma-env-preprocessor": "^0.1.1",
77
89
  "karma-firefox-launcher": "^2.1.3",
78
90
  "karma-mocha": "^2.0.1",
79
- "karma-sinon-chai": "^2.0.2",
80
91
  "karma-webpack": "^5.0.1",
81
- "mocha": "^10.8.2",
92
+ "mocha": "^11.7.5",
82
93
  "mocha-test-container-support": "^0.2.0",
83
94
  "npm-run-all": "^4.1.5",
84
- "puppeteer": "^23.1.1",
95
+ "puppeteer": "^24.32.1",
85
96
  "rollup": "^4.31.0",
86
- "sinon": "^17.0.1",
87
- "sinon-chai": "^3.7.0",
97
+ "sinon": "^21.0.0",
98
+ "sinon-chai": "^4.0.1",
99
+ "typescript": "^5.9.3",
88
100
  "webpack": "^5.97.1"
89
101
  }
90
102
  }
package/dist/index.es.js DELETED
@@ -1,725 +0,0 @@
1
- import { snippetCompletion, autocompletion, closeBrackets } from '@codemirror/autocomplete';
2
- import { defaultKeymap } from '@codemirror/commands';
3
- import { syntaxHighlighting, HighlightStyle, syntaxTree, bracketMatching, indentOnInput } from '@codemirror/language';
4
- import { linter as linter$1, setDiagnosticsEffect } from '@codemirror/lint';
5
- import { Facet, Compartment, EditorState } from '@codemirror/state';
6
- import { EditorView, tooltips, keymap, placeholder } from '@codemirror/view';
7
- import { cmFeelLinter } from '@bpmn-io/feel-lint';
8
- import { tags } from '@lezer/highlight';
9
- import { snippets, keywordCompletions, feel } from '@bpmn-io/lang-feel';
10
- import { domify } from 'min-dom';
11
- import { camundaBuiltins } from '@camunda/feel-builtins';
12
-
13
- var linter = [ linter$1(cmFeelLinter()) ];
14
-
15
- const baseTheme = EditorView.theme({
16
- '& .cm-content': {
17
- padding: '0px',
18
- },
19
- '& .cm-line': {
20
- padding: '0px',
21
- },
22
- '&.cm-editor.cm-focused': {
23
- outline: 'none',
24
- },
25
- '& .cm-completionInfo': {
26
- whiteSpace: 'pre-wrap',
27
- overflow: 'hidden',
28
- textOverflow: 'ellipsis'
29
- },
30
- '&.cm-editor': {
31
- height: '100%',
32
- },
33
-
34
- // Don't wrap whitespace for custom HTML
35
- '& .cm-completionInfo > *': {
36
- whiteSpace: 'normal'
37
- },
38
- '& .cm-completionInfo ul': {
39
- margin: 0,
40
- paddingLeft: '15px'
41
- },
42
- '& .cm-completionInfo pre': {
43
- marginBottom: 0,
44
- whiteSpace: 'pre-wrap'
45
- },
46
- '& .cm-completionInfo p': {
47
- marginTop: 0,
48
- },
49
- '& .cm-completionInfo p:not(:last-of-type)': {
50
- marginBottom: 0,
51
- }
52
- });
53
-
54
- const highlightTheme = EditorView.baseTheme({
55
- '& .variableName': {
56
- color: '#10f'
57
- },
58
- '& .number': {
59
- color: '#164'
60
- },
61
- '& .string': {
62
- color: '#a11'
63
- },
64
- '& .bool': {
65
- color: '#219'
66
- },
67
- '& .function': {
68
- color: '#aa3731',
69
- fontWeight: 'bold'
70
- },
71
- '& .control': {
72
- color: '#708'
73
- }
74
- });
75
-
76
- const syntaxClasses = syntaxHighlighting(
77
- HighlightStyle.define([
78
- { tag: tags.variableName, class: 'variableName' },
79
- { tag: tags.name, class: 'variableName' },
80
- { tag: tags.number, class: 'number' },
81
- { tag: tags.string, class: 'string' },
82
- { tag: tags.bool, class: 'bool' },
83
- { tag: tags.function(tags.variableName), class: 'function' },
84
- { tag: tags.function(tags.special(tags.variableName)), class: 'function' },
85
- { tag: tags.controlKeyword, class: 'control' },
86
- { tag: tags.operatorKeyword, class: 'control' }
87
- ])
88
- );
89
-
90
- var theme = [ baseTheme, highlightTheme, syntaxClasses ];
91
-
92
- // helpers ///////////////////////////////
93
-
94
- function _isEmpty(node) {
95
- return node && node.from === node.to;
96
- }
97
-
98
- /**
99
- * @param {any} node
100
- * @param {number} pos
101
- *
102
- * @return {boolean}
103
- */
104
- function isEmpty(node, pos) {
105
-
106
- // For the special case of empty nodes, we need to check the current node
107
- // as well. The previous node could be part of another token, e.g.
108
- // when typing functions "abs(".
109
- const nextNode = node.nextSibling;
110
-
111
- return _isEmpty(node) || (
112
- nextNode && nextNode.from === pos && _isEmpty(nextNode)
113
- );
114
- }
115
-
116
- function isVariableName(node) {
117
- return node && node.parent && node.parent.name === 'VariableName';
118
- }
119
-
120
- function isPathExpression(node) {
121
- if (!node) {
122
- return false;
123
- }
124
-
125
- if (node.name === 'PathExpression') {
126
- return true;
127
- }
128
-
129
- return isPathExpression(node.parent);
130
- }
131
-
132
- /**
133
- * @typedef { import('../core').Variable } Variable
134
- * @typedef { import('@codemirror/autocomplete').CompletionSource } CompletionSource
135
- */
136
-
137
- /**
138
- * @param { {
139
- * variables?: Variable[],
140
- * } } options
141
- *
142
- * @return { CompletionSource }
143
- */
144
- function pathExpressionCompletion({ variables }) {
145
-
146
- return (context) => {
147
-
148
- const nodeBefore = syntaxTree(context.state).resolve(context.pos, -1);
149
-
150
- if (!isPathExpression(nodeBefore)) {
151
- return;
152
- }
153
-
154
- const expression = findPathExpression(nodeBefore);
155
-
156
- // if the cursor is directly after the `.`, variable starts at the cursor position
157
- const from = nodeBefore === expression ? context.pos : nodeBefore.from;
158
-
159
- const path = getPath(expression, context);
160
-
161
- let options = variables;
162
- for (var i = 0; i < path.length - 1; i++) {
163
- var childVar = options.find(val => val.name === path[i].name);
164
-
165
- if (!childVar) {
166
- return null;
167
- }
168
-
169
- // only suggest if variable type matches
170
- if (
171
- childVar.isList !== 'optional' &&
172
- !!childVar.isList !== path[i].isList
173
- ) {
174
- return;
175
- }
176
-
177
- options = childVar.entries;
178
- }
179
-
180
- if (!options) return;
181
-
182
- options = options.map(v => ({
183
- label: v.name,
184
- type: 'variable',
185
- info: v.info,
186
- detail: v.detail
187
- }));
188
-
189
- const result = {
190
- from: from,
191
- options: options
192
- };
193
-
194
- return result;
195
- };
196
- }
197
-
198
-
199
- function findPathExpression(node) {
200
- while (node) {
201
- if (node.name === 'PathExpression') {
202
- return node;
203
- }
204
- node = node.parent;
205
- }
206
- }
207
-
208
- // parses the path expression into a list of variable names with type information
209
- // e.g. foo[0].bar => [ { name: 'foo', isList: true }, { name: 'bar', isList: false } ]
210
- function getPath(node, context) {
211
- let path = [];
212
-
213
- for (let child = node.firstChild; child; child = child.nextSibling) {
214
- if (child.name === 'PathExpression') {
215
- path.push(...getPath(child, context));
216
- } else if (child.name === 'FilterExpression') {
217
- path.push(...getFilter(child, context));
218
- }
219
- else {
220
- path.push({
221
- name: getNodeContent(child, context),
222
- isList: false
223
- });
224
- }
225
- }
226
- return path;
227
- }
228
-
229
- function getFilter(node, context) {
230
- const list = node.firstChild;
231
-
232
- if (list.name === 'PathExpression') {
233
- const path = getPath(list, context);
234
- const last = path[path.length - 1];
235
- last.isList = true;
236
-
237
- return path;
238
- }
239
-
240
- return [ {
241
- name: getNodeContent(list, context),
242
- isList: true
243
- } ];
244
- }
245
-
246
- function getNodeContent(node, context) {
247
- return context.state.sliceDoc(node.from, node.to);
248
- }
249
-
250
- /**
251
- * @typedef { import('../core').Variable } Variable
252
- * @typedef { import('@codemirror/autocomplete').CompletionSource } CompletionSource
253
- */
254
-
255
- /**
256
- * @param { {
257
- * variables?: Variable[],
258
- * builtins?: Variable[]
259
- * } } options
260
- *
261
- * @return { CompletionSource }
262
- */
263
- function variableCompletion({ variables = [], builtins = [] }) {
264
-
265
- const options = getVariableSuggestions(variables, builtins);
266
-
267
- if (!options.length) {
268
- return (context) => null;
269
- }
270
-
271
- return (context) => {
272
-
273
- const {
274
- pos,
275
- state
276
- } = context;
277
-
278
- // in most cases, use what is typed before the cursor
279
- const nodeBefore = syntaxTree(state).resolve(pos, -1);
280
-
281
- if (isEmpty(nodeBefore, pos)) {
282
- return context.explicit ? {
283
- from: pos,
284
- options
285
- } : null;
286
- }
287
-
288
- // only auto-complete variables
289
- if (!isVariableName(nodeBefore) || isPathExpression(nodeBefore)) {
290
- return null;
291
- }
292
-
293
- return {
294
- from: nodeBefore.from,
295
- options
296
- };
297
- };
298
- }
299
-
300
- /**
301
- * @param { Variable[] } variables
302
- * @param { Variable[] } builtins
303
- *
304
- * @returns {import('@codemirror/autocomplete').Completion[]}
305
- */
306
- function getVariableSuggestions(variables, builtins) {
307
- return [].concat(
308
- variables.map(v => createVariableSuggestion(v)),
309
- builtins.map(b => createVariableSuggestion(b))
310
- );
311
- }
312
-
313
- /**
314
- * @param {import('..').Variable} variable
315
- * @param {number} boost
316
-
317
- * @returns {import('@codemirror/autocomplete').Completion}
318
- */
319
- function createVariableSuggestion(variable, boost) {
320
- if (variable.type === 'function') {
321
- return createFunctionVariable(variable, boost);
322
- }
323
-
324
- return {
325
- label: variable.name,
326
- type: 'variable',
327
- info: variable.info,
328
- detail: variable.detail,
329
- boost
330
- };
331
- }
332
-
333
- /**
334
- * @param {import('..').Variable} variable
335
- * @param {number} boost
336
- *
337
- * @returns {import('@codemirror/autocomplete').Completion}
338
- */
339
- function createFunctionVariable(variable, boost) {
340
- const {
341
- name,
342
- info,
343
- detail,
344
- params = []
345
- } = variable;
346
-
347
- const paramsWithNames = params.map(({ name, type }, index) => ({
348
- name: name || `param ${index + 1}`,
349
- type
350
- }));
351
-
352
- const template = `${name}(${paramsWithNames.map(p => '${' + p.name + '}').join(', ')})`;
353
-
354
- const paramsSignature = paramsWithNames.map(({ name, type }) => (
355
- type ? `${name}: ${type}` : name
356
- )).join(', ');
357
- const label = `${name}(${paramsSignature})`;
358
-
359
- return snippetCompletion(template, {
360
- label,
361
- type: 'function',
362
- info,
363
- detail,
364
- boost
365
- });
366
- }
367
-
368
- /**
369
- * @typedef { import('../core').Variable } Variable
370
- * @typedef { import('@codemirror/autocomplete').CompletionSource } CompletionSource
371
- */
372
-
373
- /**
374
- * @param { {
375
- * variables?: Variable[],
376
- * builtins?: Variable[]
377
- * } } options
378
- *
379
- * @return { CompletionSource[] }
380
- */
381
- function completions({ variables = [], builtins = [] }) {
382
-
383
- return [
384
- pathExpressionCompletion({ variables }),
385
- variableCompletion({ variables, builtins }),
386
- snippets,
387
- ...keywordCompletions
388
- ];
389
- }
390
-
391
- /**
392
- * @typedef { 'expression' | 'unaryTests' } Dialect
393
- */
394
-
395
- /**
396
- * @typedef { 'camunda' | undefined } ParserDialect
397
- */
398
-
399
- /**
400
- * @param { {
401
- * dialect?: Dialect,
402
- * parserDialect?: ParserDialect,
403
- * context?: Record<string, any>,
404
- * completions?: import('@codemirror/autocomplete').CompletionSource[]
405
- * } } options
406
- *
407
- * @return { import('@codemirror/language').LanguageSupport }
408
- */
409
- function language(options) {
410
- return feel(options);
411
- }
412
-
413
- /**
414
- * @param { import('../core').Variable[] } variables
415
- *
416
- * @return {Record<string, any>}
417
- */
418
- function createContext(variables) {
419
- return variables.slice().reverse().reduce((context, builtin) => {
420
- context[builtin.name] = () => {};
421
-
422
- return context;
423
- }, {});
424
- }
425
-
426
- /**
427
- * @typedef { import('../language').Dialect } Dialect
428
- * @typedef { import('../language').ParserDialect } ParserDialect
429
- * @typedef { import('..').Variable } Variable
430
- */
431
-
432
- /**
433
- * @type {Facet<Variable[]>}
434
- */
435
- const builtinsFacet = Facet.define();
436
-
437
- /**
438
- * @type {Facet<Variable[]>}
439
- */
440
- const variablesFacet = Facet.define();
441
-
442
- /**
443
- * @type {Facet<Dialect>}
444
- */
445
- const dialectFacet = Facet.define();
446
-
447
- /**
448
- * @type {Facet<ParserDialect>}
449
- */
450
- const parserDialectFacet = Facet.define();
451
-
452
- /**
453
- * @typedef {object} Variable
454
- * @property {string} name name or key of the variable
455
- * @property {string} [info] short information about the variable, e.g. type
456
- * @property {string} [detail] longer description of the variable content
457
- * @property {boolean} [isList] whether the variable is a list
458
- * @property {Array<Variable>} [schema] array of child variables if the variable is a context or list
459
- * @property {'function'|'variable'} [type] type of the variable
460
- * @property {Array<{name: string, type: string}>} [params] function parameters
461
- */
462
-
463
- /**
464
- * @typedef { {
465
- * dialect?: import('../language').Dialect,
466
- * parserDialect?: import('../language').ParserDialect,
467
- * variables?: Variable[],
468
- * builtins?: Variable[]
469
- * } } CoreConfig
470
- *
471
- * @typedef { import('@codemirror/autocomplete').CompletionSource } CompletionSource
472
- * @typedef { import('@codemirror/state').Extension } Extension
473
- */
474
-
475
- /**
476
- * @param { CoreConfig & { completions?: CompletionSource[] } } config
477
- *
478
- * @return { Extension }
479
- */
480
- function configure({
481
- dialect = 'expression',
482
- parserDialect,
483
- variables = [],
484
- builtins = [],
485
- completions: completions$1 = completions({ builtins, variables })
486
- }) {
487
-
488
- const context = createContext([ ...variables, ...builtins ]);
489
-
490
- return [
491
- dialectFacet.of(dialect),
492
- builtinsFacet.of(builtins),
493
- variablesFacet.of(variables),
494
- parserDialectFacet.of(parserDialect),
495
- language({
496
- dialect,
497
- parserDialect,
498
- context,
499
- completions: completions$1
500
- })
501
- ];
502
- }
503
-
504
- /**
505
- * @param {import('@codemirror/state').EditorState } state
506
- *
507
- * @return { CoreConfig }
508
- */
509
- function get(state) {
510
-
511
- const builtins = state.facet(builtinsFacet)[0];
512
- const variables = state.facet(variablesFacet)[0];
513
- const dialect = state.facet(dialectFacet)[0];
514
- const parserDialect = state.facet(parserDialectFacet)[0];
515
-
516
- return {
517
- builtins,
518
- variables,
519
- dialect,
520
- parserDialect
521
- };
522
- }
523
-
524
- const domifiedBuiltins = camundaBuiltins.map(builtin => ({
525
- ...builtin,
526
- info: () => domify(builtin.info),
527
- }));
528
-
529
- /**
530
- * @typedef { import('./core').Variable } Variable
531
- */
532
-
533
- /**
534
- * @typedef { import('./language').Dialect } Dialect
535
- * @typedef { import('./language').ParserDialect } ParserDialect
536
- */
537
-
538
- const coreConf = new Compartment();
539
- const placeholderConf = new Compartment();
540
-
541
-
542
- /**
543
- * Creates a FEEL editor in the supplied container
544
- *
545
- * @param {Object} config
546
- * @param {DOMNode} config.container
547
- * @param {Extension[]} [config.extensions]
548
- * @param {Dialect} [config.dialect='expression']
549
- * @param {ParserDialect} [config.parserDialect]
550
- * @param {DOMNode|String} [config.tooltipContainer]
551
- * @param {Function} [config.onChange]
552
- * @param {Function} [config.onKeyDown]
553
- * @param {Function} [config.onLint]
554
- * @param {Boolean} [config.readOnly]
555
- * @param {String} [config.value]
556
- * @param {Variable[]} [config.variables]
557
- * @param {Variable[]} [config.builtins]
558
- */
559
- function FeelEditor({
560
- extensions: editorExtensions = [],
561
- dialect = 'expression',
562
- parserDialect,
563
- container,
564
- contentAttributes = {},
565
- tooltipContainer,
566
- onChange = () => {},
567
- onKeyDown = () => {},
568
- onLint = () => {},
569
- placeholder: placeholder$1 = '',
570
- readOnly = false,
571
- value = '',
572
- builtins = domifiedBuiltins,
573
- variables = []
574
- }) {
575
-
576
- const changeHandler = EditorView.updateListener.of((update) => {
577
- if (update.docChanged) {
578
- onChange(update.state.doc.toString());
579
- }
580
- });
581
-
582
- const lintHandler = EditorView.updateListener.of((update) => {
583
- const diagnosticEffects = update.transactions
584
- .flatMap(t => t.effects)
585
- .filter(effect => effect.is(setDiagnosticsEffect));
586
-
587
- if (!diagnosticEffects.length) {
588
- return;
589
- }
590
-
591
- const messages = diagnosticEffects.flatMap(effect => effect.value);
592
-
593
- onLint(messages);
594
- });
595
-
596
- const keyHandler = EditorView.domEventHandlers(
597
- {
598
- keydown: onKeyDown
599
- }
600
- );
601
-
602
- if (typeof tooltipContainer === 'string') {
603
- tooltipContainer = document.querySelector(tooltipContainer);
604
- }
605
-
606
- const tooltipLayout = tooltipContainer ? tooltips({
607
- tooltipSpace: function() {
608
- return tooltipContainer.getBoundingClientRect();
609
- }
610
- }) : [];
611
-
612
- const extensions = [
613
- autocompletion(),
614
- coreConf.of(configure({
615
- dialect,
616
- builtins,
617
- variables,
618
- parserDialect
619
- })),
620
- bracketMatching(),
621
- indentOnInput(),
622
- closeBrackets(),
623
- EditorView.contentAttributes.of(contentAttributes),
624
- changeHandler,
625
- keyHandler,
626
- keymap.of([
627
- ...defaultKeymap,
628
- ]),
629
- linter,
630
- lintHandler,
631
- tooltipLayout,
632
- placeholderConf.of(placeholder(placeholder$1)),
633
- theme,
634
- ...editorExtensions
635
- ];
636
-
637
- if (readOnly) {
638
- extensions.push(EditorView.editable.of(false));
639
- }
640
-
641
- this._cmEditor = new EditorView({
642
- state: EditorState.create({
643
- doc: value,
644
- extensions
645
- }),
646
- parent: container
647
- });
648
-
649
- return this;
650
- }
651
-
652
- /**
653
- * Replaces the content of the Editor
654
- *
655
- * @param {String} value
656
- */
657
- FeelEditor.prototype.setValue = function(value) {
658
- this._cmEditor.dispatch({
659
- changes: {
660
- from: 0,
661
- to: this._cmEditor.state.doc.length,
662
- insert: value,
663
- }
664
- });
665
- };
666
-
667
- /**
668
- * Sets the focus in the editor.
669
- */
670
- FeelEditor.prototype.focus = function(position) {
671
- const cmEditor = this._cmEditor;
672
-
673
- // the Codemirror `focus` method always calls `focus` with `preventScroll`,
674
- // so we have to focus + scroll manually
675
- cmEditor.contentDOM.focus();
676
- cmEditor.focus();
677
-
678
- if (typeof position === 'number') {
679
- const end = cmEditor.state.doc.length;
680
- cmEditor.dispatch({ selection: { anchor: position <= end ? position : end } });
681
- }
682
- };
683
-
684
- /**
685
- * Returns the current selection ranges. If no text is selected, a single
686
- * range with the start and end index at the cursor position will be returned.
687
- *
688
- * @returns {Object} selection
689
- * @returns {Array} selection.ranges
690
- */
691
- FeelEditor.prototype.getSelection = function() {
692
- return this._cmEditor.state.selection;
693
- };
694
-
695
- /**
696
- * Set variables to be used for autocompletion.
697
- *
698
- * @param {Variable[]} variables
699
- */
700
- FeelEditor.prototype.setVariables = function(variables) {
701
-
702
- const config = get(this._cmEditor.state);
703
-
704
- this._cmEditor.dispatch({
705
- effects: [
706
- coreConf.reconfigure(configure({
707
- ...config,
708
- variables
709
- }))
710
- ]
711
- });
712
- };
713
-
714
- /**
715
- * Update placeholder text.
716
- *
717
- * @param {string} placeholder
718
- */
719
- FeelEditor.prototype.setPlaceholder = function(placeholder$1) {
720
- this._cmEditor.dispatch({
721
- effects: placeholderConf.reconfigure(placeholder(placeholder$1))
722
- });
723
- };
724
-
725
- export { FeelEditor as default };