@bpmn-io/feel-analyzer 0.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2026 Camunda Services GmbH
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,102 @@
1
+ # FEEL Analyzer
2
+
3
+ > A library for analyzing FEEL (Friendly Enough Expression Language) expressions.
4
+
5
+ [![CI](https://github.com/bpmn-io/feel-analyzer/workflows/CI/badge.svg)](https://github.com/bpmn-io/feel-analyzer/actions?query=workflow%3ACI)
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ npm install @bpmn-io/feel-analyzer
11
+ ```
12
+
13
+ ## Usage
14
+
15
+ To get started, create a `FeelAnalyzer` instance:
16
+
17
+ ```javascript
18
+ import { FeelAnalyzer } from '@bpmn-io/feel-analyzer';
19
+
20
+ const analyzer = new FeelAnalyzer();
21
+ ```
22
+
23
+ Analyze a FEEL expression to extract input variables:
24
+
25
+ ```javascript
26
+ const result = analyzer.analyzeExpression('x + y');
27
+
28
+ console.log(result.valid); // true
29
+ console.log(result.inputs);
30
+ // [
31
+ // { name: 'x' },
32
+ // { name: 'y' }
33
+ // ]
34
+ ```
35
+
36
+ Configure the FEEL dialect (expression or unary tests):
37
+
38
+ ```javascript
39
+ const analyzer = new FeelAnalyzer({
40
+ dialect: 'unaryTests' // defaults to 'expression'
41
+ });
42
+ ```
43
+
44
+ ### Builtins
45
+
46
+ You can provide `builtins` and `reservedNameBuiltins` to exclude built-in names from input detection. Use [`@camunda/feel-builtins`](https://github.com/camunda/feel-builtins) to supply these:
47
+
48
+ ```javascript
49
+ import { FeelAnalyzer } from '@bpmn-io/feel-analyzer';
50
+ import { builtins, reservedNameBuiltins } from '@camunda/feel-builtins';
51
+
52
+ const analyzer = new FeelAnalyzer({
53
+ dialect: 'expression',
54
+ parserDialect: 'camunda',
55
+ builtins,
56
+ reservedNameBuiltins
57
+ });
58
+
59
+ const result = analyzer.analyzeExpression('sum(orders.amount) > 100');
60
+
61
+ console.log(result.inputs);
62
+ // [
63
+ // {
64
+ // name: 'orders',
65
+ // type: 'List',
66
+ // entries: [
67
+ // { name: 'amount' }
68
+ // ]
69
+ // }
70
+ // ]
71
+ ```
72
+
73
+ ### Input Variables
74
+
75
+ The analyzer extracts input variables with type information, including nested structures. The data model is aligned with [variable-resolver](https://github.com/bpmn-io/variable-resolver):
76
+
77
+ ```javascript
78
+ const result = analyzer.analyzeExpression('person.name = "John" and scores[1] > 10');
79
+
80
+ console.log(result.inputs);
81
+ // [
82
+ // {
83
+ // name: 'person',
84
+ // type: 'Context',
85
+ // entries: [
86
+ // { name: 'name' }
87
+ // ]
88
+ // },
89
+ // {
90
+ // name: 'scores',
91
+ // type: 'List'
92
+ // }
93
+ // ]
94
+ ```
95
+
96
+ ## Related
97
+
98
+ - [@bpmn-io/lezer-feel](https://github.com/bpmn-io/lezer-feel) - FEEL language definition for the [Lezer](https://lezer.codemirror.net/) parser system
99
+
100
+ ## License
101
+
102
+ MIT
@@ -0,0 +1,59 @@
1
+ import { AnalysisOptions, AnalysisResult } from './types.js';
2
+ /**
3
+ * Analyzer for FEEL expressions
4
+ */
5
+ export declare class FeelAnalyzer {
6
+ /**
7
+ * Analyze a FEEL expression
8
+ *
9
+ * @param expression - The FEEL expression to analyze
10
+ * @param options - Optional analysis configuration
11
+ * @returns Analysis result
12
+ */
13
+ analyze(expression: string, options?: AnalysisOptions): AnalysisResult;
14
+ /**
15
+ * Get configured parser based on options
16
+ */
17
+ private getConfiguredParser;
18
+ /**
19
+ * Extract built-in function names from builtins array
20
+ */
21
+ private getBuiltinNames;
22
+ /**
23
+ * Strip backticks from identifier names
24
+ */
25
+ private stripBackticks;
26
+ /**
27
+ * Extract needed input variables from the AST
28
+ */
29
+ private extractNeededInputs;
30
+ /**
31
+ * Helper to collect path parts from a PathExpression node
32
+ */
33
+ private collectPathPartsFromNode;
34
+ /**
35
+ * Extract expected input types from the AST
36
+ */
37
+ private extractInputTypes;
38
+ /**
39
+ * Track item property accesses in filter expressions
40
+ */
41
+ private trackFilterItemProperties;
42
+ /**
43
+ * Infer type from comparison with literals
44
+ */
45
+ private inferTypeFromComparison;
46
+ /**
47
+ * Extract output type information from the AST
48
+ */
49
+ private extractOutputType;
50
+ /**
51
+ * Analyze the output type of a specific node
52
+ */
53
+ private analyzeNodeOutputType;
54
+ /**
55
+ * Infer type from a runtime value
56
+ */
57
+ private inferTypeFromValue;
58
+ }
59
+ //# sourceMappingURL=FeelAnalyzer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FeelAnalyzer.d.ts","sourceRoot":"","sources":["../src/FeelAnalyzer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EACf,cAAc,EAIf,MAAM,YAAY,CAAC;AAKpB;;GAEG;AACH,qBAAa,YAAY;IAEvB;;;;;;OAMG;IACH,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,cAAc;IA+CtE;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAkC3B;;OAEG;IACH,OAAO,CAAC,eAAe;IAQvB;;OAEG;IACH,OAAO,CAAC,cAAc;IAItB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAoc3B;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAmBhC;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAyXzB;;OAEG;IACH,OAAO,CAAC,yBAAyB;IA2EjC;;OAEG;IACH,OAAO,CAAC,uBAAuB;IAgC/B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAgBzB;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAqI7B;;OAEG;IACH,OAAO,CAAC,kBAAkB;CAmB3B"}
@@ -0,0 +1,10 @@
1
+ import type { SyntaxNode } from '@lezer/common';
2
+ import type { InputVariable } from '../types';
3
+ /**
4
+ * Analyze an AST to extract input variables and infer their types.
5
+ */
6
+ export declare function analyzeForInputs(node: SyntaxNode, source: string, builtinNames: Set<string>): {
7
+ inputs: InputVariable[];
8
+ hasErrors: boolean;
9
+ };
10
+ //# sourceMappingURL=inputs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inputs.d.ts","sourceRoot":"","sources":["../../src/analyzers/inputs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEhD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AA8e9C;;GAEG;AACH,wBAAgB,gBAAgB,CAC5B,IAAI,EAAE,UAAU,EAChB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,GAAG,CAAC,MAAM,CAAC,GAC1B;IAAE,MAAM,EAAE,aAAa,EAAE,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CAejD"}
@@ -0,0 +1,62 @@
1
+ import type { SyntaxNode } from '@lezer/common';
2
+ import type { InputVariable } from '../types';
3
+ /**
4
+ * Strip backticks from identifier names
5
+ */
6
+ export declare function stripBackticks(text: string): string;
7
+ /**
8
+ * Read the source text of a node, stripping backticks
9
+ */
10
+ export declare function nodeText(node: SyntaxNode, source: string): string;
11
+ /**
12
+ * Check if a variable is defined in any active scope
13
+ */
14
+ export declare function isInScope(varName: string, scopes: Set<string>[]): boolean;
15
+ /**
16
+ * Execute `fn` with a new scope pushed onto the scope stack,
17
+ * then pop it automatically. Returns the created scope so callers
18
+ * can add names to it during processing.
19
+ */
20
+ export declare function withScope<T>(scopes: Set<string>[], initialNames: Iterable<string>, fn: (scope: Set<string>) => T): T;
21
+ /**
22
+ * Iterate over direct children of a node
23
+ */
24
+ export declare function forEachChild(node: SyntaxNode, callback: (child: SyntaxNode) => void): void;
25
+ /**
26
+ * Collect path parts from a PathExpression node (e.g. `a.b.c` → ['a', 'b', 'c'])
27
+ */
28
+ export declare function collectPathParts(node: SyntaxNode, source: string): string[];
29
+ /**
30
+ * Check if a PathExpression node has a Context as its base
31
+ */
32
+ export declare function hasContextBase(node: SyntaxNode): boolean;
33
+ /**
34
+ * Extract key names from a Context node
35
+ */
36
+ export declare function extractContextKeys(contextNode: SyntaxNode, source: string): string[];
37
+ /**
38
+ * Collect iteration variable names from a ForExpression or QuantifiedExpression
39
+ */
40
+ export declare function collectIterationVariables(node: SyntaxNode, source: string): string[];
41
+ /**
42
+ * Collect formal parameter names from a FunctionDefinition
43
+ */
44
+ export declare function collectFunctionParameters(node: SyntaxNode, source: string): string[];
45
+ /**
46
+ * Find a variable by name in an InputVariable array
47
+ */
48
+ export declare function findVariable(variables: InputVariable[], name: string): InputVariable | undefined;
49
+ /**
50
+ * Find a variable by name, or create and insert it if missing
51
+ */
52
+ export declare function findOrCreateVariable(variables: InputVariable[], name: string): InputVariable;
53
+ /**
54
+ * Build nested context entries from a dot path (e.g. ['a', 'b', 'c']).
55
+ * Creates intermediate context nodes as needed.
56
+ */
57
+ export declare function buildNestedEntries(variables: InputVariable[], pathParts: string[]): void;
58
+ /**
59
+ * Sort entries recursively for deterministic output
60
+ */
61
+ export declare function sortEntries(variable: InputVariable): void;
62
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/analyzers/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEhD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9C;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAEjE;AAID;;GAEG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,GAAG,OAAO,CAEzE;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,CAAC,EACvB,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,EACrB,YAAY,EAAE,QAAQ,CAAC,MAAM,CAAC,EAC9B,EAAE,EAAE,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,GAC9B,CAAC,CAMH;AAID;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,GAAG,IAAI,CAM1F;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAU3E;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAMxD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAWpF;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAYpF;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAYpF;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,aAAa,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAEhG;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,aAAa,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,aAAa,CAO5F;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAC9B,SAAS,EAAE,aAAa,EAAE,EAC1B,SAAS,EAAE,MAAM,EAAE,GACpB,IAAI,CAgCN;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,aAAa,GAAG,IAAI,CAOzD"}
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=feel-analyzer-backup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feel-analyzer-backup.d.ts","sourceRoot":"","sources":["../src/feel-analyzer-backup.ts"],"names":[],"mappings":""}
@@ -0,0 +1,15 @@
1
+ import { parser } from '@bpmn-io/lezer-feel';
2
+ import type { AnalysisResult, Builtin } from './types';
3
+ export interface FeelAnalyzerOptions {
4
+ dialect: 'expression' | 'unaryTests';
5
+ parserDialect: undefined | 'camunda';
6
+ builtins: Builtin[];
7
+ reservedNameBuiltins: Builtin[];
8
+ }
9
+ export declare class FeelAnalyzer {
10
+ builtinNames: string[];
11
+ parser: typeof parser;
12
+ constructor(options?: Partial<FeelAnalyzerOptions>);
13
+ analyzeExpression(expression: string): AnalysisResult;
14
+ }
15
+ //# sourceMappingURL=feel-analyzer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feel-analyzer.d.ts","sourceRoot":"","sources":["../src/feel-analyzer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAkB,MAAM,qBAAqB,CAAC;AAE7D,OAAO,KAAK,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAKvD,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,YAAY,GAAG,YAAY,CAAC;IACrC,aAAa,EAAE,SAAS,GAAG,SAAS,CAAC;IACrC,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,oBAAoB,EAAE,OAAO,EAAE,CAAC;CACjC;AAED,qBAAa,YAAY;IACvB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,MAAM,EAAE,OAAO,MAAM,CAAC;gBAEV,OAAO,GAAE,OAAO,CAAC,mBAAmB,CAAM;IActD,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,cAAc;CAUtD"}
@@ -0,0 +1,4 @@
1
+ export { FeelAnalyzer } from './feel-analyzer';
2
+ export type { FeelAnalyzerOptions } from './feel-analyzer';
3
+ export type { Builtin, AnalysisResult, InputVariable } from './types';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE/C,YAAY,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAC3D,YAAY,EAAE,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,639 @@
1
+ import { trackVariables, parser } from '@bpmn-io/lezer-feel';
2
+
3
+ /**
4
+ * Strip backticks from identifier names
5
+ */
6
+ function stripBackticks(text) {
7
+ return text.replace(/^`|`$/g, '');
8
+ }
9
+ /**
10
+ * Read the source text of a node, stripping backticks
11
+ */
12
+ function nodeText(node, source) {
13
+ return stripBackticks(source.substring(node.from, node.to));
14
+ }
15
+ // --- Scope helpers ---
16
+ /**
17
+ * Check if a variable is defined in any active scope
18
+ */
19
+ function isInScope(varName, scopes) {
20
+ return scopes.some((scope) => scope.has(varName));
21
+ }
22
+ /**
23
+ * Execute `fn` with a new scope pushed onto the scope stack,
24
+ * then pop it automatically. Returns the created scope so callers
25
+ * can add names to it during processing.
26
+ */
27
+ function withScope(scopes, initialNames, fn) {
28
+ const scope = new Set(initialNames);
29
+ scopes.push(scope);
30
+ const result = fn(scope);
31
+ scopes.pop();
32
+ return result;
33
+ }
34
+ // --- AST traversal helpers ---
35
+ /**
36
+ * Iterate over direct children of a node
37
+ */
38
+ function forEachChild(node, callback) {
39
+ let child = node.firstChild;
40
+ while (child) {
41
+ callback(child);
42
+ child = child.nextSibling;
43
+ }
44
+ }
45
+ /**
46
+ * Collect path parts from a PathExpression node (e.g. `a.b.c` → ['a', 'b', 'c'])
47
+ */
48
+ function collectPathParts(node, source) {
49
+ const parts = [];
50
+ forEachChild(node, (child) => {
51
+ if (child.name === 'PathExpression') {
52
+ parts.push(...collectPathParts(child, source));
53
+ }
54
+ else if (child.name === 'VariableName') {
55
+ parts.push(nodeText(child, source));
56
+ }
57
+ });
58
+ return parts;
59
+ }
60
+ /**
61
+ * Check if a PathExpression node has a Context as its base
62
+ */
63
+ function hasContextBase(node) {
64
+ const firstChild = node.firstChild;
65
+ if (!firstChild)
66
+ return false;
67
+ if (firstChild.name === 'Context')
68
+ return true;
69
+ if (firstChild.name === 'PathExpression')
70
+ return hasContextBase(firstChild);
71
+ return false;
72
+ }
73
+ /**
74
+ * Extract key names from a Context node
75
+ */
76
+ function extractContextKeys(contextNode, source) {
77
+ const keys = [];
78
+ forEachChild(contextNode, (child) => {
79
+ if (child.name === 'ContextEntry') {
80
+ const keyName = child.getChild('Key')?.getChild('Name');
81
+ if (keyName) {
82
+ keys.push(nodeText(keyName, source));
83
+ }
84
+ }
85
+ });
86
+ return keys;
87
+ }
88
+ /**
89
+ * Collect iteration variable names from a ForExpression or QuantifiedExpression
90
+ */
91
+ function collectIterationVariables(node, source) {
92
+ const vars = [];
93
+ const inExpressions = node.getChild('InExpressions');
94
+ if (inExpressions) {
95
+ forEachChild(inExpressions, (child) => {
96
+ if (child.name === 'InExpression') {
97
+ const id = child.getChild('Name')?.getChild('Identifier');
98
+ if (id)
99
+ vars.push(source.substring(id.from, id.to));
100
+ }
101
+ });
102
+ }
103
+ return vars;
104
+ }
105
+ /**
106
+ * Collect formal parameter names from a FunctionDefinition
107
+ */
108
+ function collectFunctionParameters(node, source) {
109
+ const params = [];
110
+ const formalParams = node.getChild('FormalParameters');
111
+ if (formalParams) {
112
+ forEachChild(formalParams, (child) => {
113
+ if (child.name === 'FormalParameter') {
114
+ const id = child.getChild('ParameterName')?.getChild('Name')?.getChild('Identifier');
115
+ if (id)
116
+ params.push(source.substring(id.from, id.to));
117
+ }
118
+ });
119
+ }
120
+ return params;
121
+ }
122
+ /**
123
+ * Find a variable by name in an InputVariable array
124
+ */
125
+ function findVariable(variables, name) {
126
+ return variables.find((v) => v.name === name);
127
+ }
128
+ /**
129
+ * Find a variable by name, or create and insert it if missing
130
+ */
131
+ function findOrCreateVariable(variables, name) {
132
+ let variable = findVariable(variables, name);
133
+ if (!variable) {
134
+ variable = { name };
135
+ variables.push(variable);
136
+ }
137
+ return variable;
138
+ }
139
+ /**
140
+ * Build nested context entries from a dot path (e.g. ['a', 'b', 'c']).
141
+ * Creates intermediate context nodes as needed.
142
+ */
143
+ function buildNestedEntries(variables, pathParts) {
144
+ const rootVar = findOrCreateVariable(variables, pathParts[0]);
145
+ if (pathParts.length <= 1)
146
+ return;
147
+ if (!rootVar.type) {
148
+ rootVar.type = 'Context';
149
+ rootVar.entries = rootVar.entries || [];
150
+ }
151
+ if (rootVar.type !== 'Context')
152
+ return;
153
+ let currentLevel = rootVar.entries;
154
+ for (let i = 1; i < pathParts.length; i++) {
155
+ const part = pathParts[i];
156
+ const isLast = i === pathParts.length - 1;
157
+ let entry = findVariable(currentLevel, part);
158
+ if (!entry) {
159
+ entry = isLast
160
+ ? { name: part }
161
+ : { name: part, type: 'Context', entries: [] };
162
+ currentLevel.push(entry);
163
+ }
164
+ else if (!isLast && !entry.type) {
165
+ entry.type = 'Context';
166
+ entry.entries = entry.entries || [];
167
+ }
168
+ if (!isLast) {
169
+ entry.entries = entry.entries || [];
170
+ currentLevel = entry.entries;
171
+ }
172
+ }
173
+ }
174
+ /**
175
+ * Sort entries recursively for deterministic output
176
+ */
177
+ function sortEntries(variable) {
178
+ if (variable.entries) {
179
+ variable.entries.sort((a, b) => a.name.localeCompare(b.name));
180
+ for (const entry of variable.entries) {
181
+ sortEntries(entry);
182
+ }
183
+ }
184
+ }
185
+
186
+ const ITERATION_KEYWORDS = new Set(['for', 'return', 'some', 'every', 'InExpressions', 'satisfies']);
187
+ /**
188
+ * Walk the AST collecting all external variable references (inputs).
189
+ * Local scopes (context keys, iteration vars, function params) are tracked
190
+ * so that locally-defined names are excluded from the result.
191
+ */
192
+ function extractInputNames(node, source, builtinNames) {
193
+ const inputs = new Set();
194
+ const localScopes = [new Set()];
195
+ let hasErrors = false;
196
+ function isExternal(name, filterCtx) {
197
+ return !isInScope(name, localScopes)
198
+ && !builtinNames.has(name)
199
+ && !(filterCtx !== 'none' && name === 'item');
200
+ }
201
+ const collectInputs = (node, filterCtx = 'none') => {
202
+ const { name: nodeName } = node;
203
+ if (node.type.isError) {
204
+ hasErrors = true;
205
+ return;
206
+ }
207
+ if (nodeName === 'FunctionInvocation') {
208
+ const funcNameNode = node.getChild('VariableName');
209
+ if (funcNameNode) {
210
+ const funcName = nodeText(funcNameNode, source);
211
+ if (isExternal(funcName, filterCtx)) {
212
+ inputs.add(funcName);
213
+ }
214
+ }
215
+ forEachChild(node, (child) => {
216
+ if (child.name !== 'VariableName' && child.name !== '(' && child.name !== ')') {
217
+ collectInputs(child, filterCtx);
218
+ }
219
+ });
220
+ return;
221
+ }
222
+ if (nodeName === 'PathExpression') {
223
+ if (hasContextBase(node)) {
224
+ forEachChild(node, (child) => collectInputs(child, filterCtx));
225
+ }
226
+ else {
227
+ const pathParts = collectPathParts(node, source);
228
+ if (pathParts.length > 0 && isExternal(pathParts[0], filterCtx)) {
229
+ inputs.add(pathParts.join('.'));
230
+ }
231
+ }
232
+ return;
233
+ }
234
+ if (nodeName === 'VariableName'
235
+ && node.parent?.name !== 'PathExpression'
236
+ && node.parent?.name !== 'FunctionInvocation') {
237
+ const varName = nodeText(node, source);
238
+ const isImplicitFilterProp = filterCtx === 'variable-list' && varName !== 'item';
239
+ if (isExternal(varName, filterCtx) && !isImplicitFilterProp) {
240
+ inputs.add(varName);
241
+ }
242
+ return;
243
+ }
244
+ if (nodeName === 'Context' && node.parent?.name !== 'List') {
245
+ withScope(localScopes, [], (scope) => {
246
+ forEachChild(node, (child) => {
247
+ if (child.name === 'ContextEntry') {
248
+ forEachChild(child, (entryChild) => {
249
+ if (entryChild.name !== 'Key')
250
+ collectInputs(entryChild, filterCtx);
251
+ });
252
+ const keyName = child.getChild('Key')?.getChild('Name');
253
+ if (keyName)
254
+ scope.add(nodeText(keyName, source));
255
+ }
256
+ });
257
+ });
258
+ return;
259
+ }
260
+ if (nodeName === 'FilterExpression') {
261
+ let newFilterCtx = 'none';
262
+ const scopeNames = ['item'];
263
+ const listNode = node.getChild('List');
264
+ if (listNode) {
265
+ forEachChild(listNode, (child) => {
266
+ if (child.name === 'Context') {
267
+ scopeNames.push(...extractContextKeys(child, source));
268
+ }
269
+ });
270
+ newFilterCtx = 'list-literal';
271
+ }
272
+ else {
273
+ forEachChild(node, (child) => {
274
+ if (child.name === 'VariableName') {
275
+ collectInputs(child, 'none');
276
+ newFilterCtx = 'variable-list';
277
+ }
278
+ });
279
+ }
280
+ withScope(localScopes, scopeNames, () => {
281
+ forEachChild(node, (child) => {
282
+ if (child.name === 'Comparison' || child.name === 'Expression') {
283
+ collectInputs(child, newFilterCtx);
284
+ }
285
+ });
286
+ });
287
+ return;
288
+ }
289
+ if (nodeName === 'ForExpression' || nodeName === 'QuantifiedExpression') {
290
+ const iterVars = collectIterationVariables(node, source);
291
+ const inExp = node.getChild('InExpressions');
292
+ if (inExp) {
293
+ forEachChild(inExp, (child) => {
294
+ if (child.name === 'InExpression') {
295
+ forEachChild(child, (innerChild) => {
296
+ if (innerChild.name !== 'Name' && innerChild.name !== 'in' && innerChild.name !== 'Identifier') {
297
+ collectInputs(innerChild, filterCtx);
298
+ }
299
+ });
300
+ }
301
+ });
302
+ }
303
+ withScope(localScopes, iterVars, () => {
304
+ forEachChild(node, (child) => {
305
+ if (!ITERATION_KEYWORDS.has(child.name)) {
306
+ collectInputs(child, 'none');
307
+ }
308
+ });
309
+ });
310
+ return;
311
+ }
312
+ if (nodeName === 'FunctionDefinition') {
313
+ const params = collectFunctionParameters(node, source);
314
+ withScope(localScopes, params, () => {
315
+ if (hasErrors)
316
+ return;
317
+ const body = node.getChild('FunctionBody');
318
+ if (body)
319
+ collectInputs(body, 'none');
320
+ });
321
+ return;
322
+ }
323
+ forEachChild(node, (child) => collectInputs(child, filterCtx));
324
+ };
325
+ collectInputs(node);
326
+ return {
327
+ inputs: Array.from(inputs).sort(),
328
+ hasErrors,
329
+ };
330
+ }
331
+ /**
332
+ * Initialize input variables based on collected variable names.
333
+ * Dotted paths like "a.b.c" create nested context structures.
334
+ */
335
+ function initializeInputVariables(collectedInputs) {
336
+ const variables = [];
337
+ for (const input of collectedInputs) {
338
+ buildNestedEntries(variables, input.split('.'));
339
+ }
340
+ return variables;
341
+ }
342
+ /**
343
+ * Check whether a node or its nested ArithmeticExpression children
344
+ * contain string or number literals.
345
+ */
346
+ function checkLiteralsInNode(node) {
347
+ let hasString = false;
348
+ let hasNumber = false;
349
+ forEachChild(node, (child) => {
350
+ if (child.name === 'StringLiteral')
351
+ hasString = true;
352
+ else if (child.name === 'NumericLiteral')
353
+ hasNumber = true;
354
+ else if (child.name === 'ArithmeticExpression') {
355
+ const nested = checkLiteralsInNode(child);
356
+ hasString = hasString || nested.hasString;
357
+ hasNumber = hasNumber || nested.hasNumber;
358
+ }
359
+ });
360
+ return { hasString, hasNumber };
361
+ }
362
+ /**
363
+ * Infer a type for all variable references inside a node.
364
+ * Used when surrounding context (e.g. arithmetic with a number literal)
365
+ * implies the type of unknown variables.
366
+ */
367
+ function inferTypeForVariablesInNode(node, source, inputs, localScopes, inferredType) {
368
+ if (node.name === 'VariableName' && node.parent?.name !== 'PathExpression') {
369
+ const varName = nodeText(node, source);
370
+ const variable = findVariable(inputs, varName);
371
+ if (!isInScope(varName, localScopes) && variable && !variable.type) {
372
+ variable.type = inferredType;
373
+ }
374
+ }
375
+ else if (node.name === 'PathExpression') {
376
+ const pathParts = collectPathParts(node, source);
377
+ if (pathParts.length > 0) {
378
+ const rootVar = pathParts[0];
379
+ const variable = findVariable(inputs, rootVar);
380
+ if (!isInScope(rootVar, localScopes) && variable && !variable.type) {
381
+ variable.type = inferredType;
382
+ }
383
+ }
384
+ }
385
+ else {
386
+ forEachChild(node, (child) => {
387
+ inferTypeForVariablesInNode(child, source, inputs, localScopes, inferredType);
388
+ });
389
+ }
390
+ }
391
+ /**
392
+ * Track which properties are accessed on `item` inside a filter expression
393
+ * and record them as entries on the list variable.
394
+ */
395
+ function trackFilterItemProperties(node, source, listVarName, inputs, localScopes) {
396
+ const listVar = listVarName ? findVariable(inputs, listVarName) : null;
397
+ if (!listVar)
398
+ return;
399
+ const visit = (node) => {
400
+ if (listVar.type !== 'List')
401
+ return;
402
+ if (node.name === 'PathExpression') {
403
+ const pathParts = [];
404
+ forEachChild(node, (child) => {
405
+ if (child.name === 'VariableName') {
406
+ pathParts.push(nodeText(child, source));
407
+ }
408
+ });
409
+ // `item.prop` → record 'prop' as an item entry
410
+ if (pathParts.length > 1 && pathParts[0] === 'item') {
411
+ const entries = listVar.entries || [];
412
+ for (let i = 1; i < pathParts.length; i++) {
413
+ if (!findVariable(entries, pathParts[i])) {
414
+ entries.push({ name: pathParts[i] });
415
+ }
416
+ }
417
+ listVar.entries = entries;
418
+ }
419
+ }
420
+ else if (node.name === 'VariableName') {
421
+ const varName = nodeText(node, source);
422
+ // Standalone variable inside filter (not `item`, not local) → item entry
423
+ if (!isInScope(varName, localScopes) && varName !== 'item' && node.parent?.name !== 'PathExpression') {
424
+ const entries = listVar.entries || [];
425
+ if (!findVariable(entries, varName)) {
426
+ entries.push({ name: varName });
427
+ }
428
+ listVar.entries = entries;
429
+ }
430
+ }
431
+ forEachChild(node, visit);
432
+ };
433
+ visit(node);
434
+ }
435
+ /**
436
+ * Infer type of a variable from a direct comparison with a literal
437
+ * (e.g. `x > 5` → x is Number, `name = "foo"` → name is String).
438
+ */
439
+ function inferTypeFromComparison(varNode, literalNode, source, inputs, localScopes) {
440
+ if (varNode.name !== 'VariableName')
441
+ return;
442
+ const varName = nodeText(varNode, source);
443
+ const variable = findVariable(inputs, varName);
444
+ if (isInScope(varName, localScopes) || !variable)
445
+ return;
446
+ if (variable.type)
447
+ return;
448
+ const literalTypeMap = {
449
+ NumericLiteral: 'Number',
450
+ StringLiteral: 'String',
451
+ BooleanLiteral: 'Boolean',
452
+ };
453
+ const inferred = literalTypeMap[literalNode.name];
454
+ if (inferred)
455
+ variable.type = inferred;
456
+ }
457
+ /**
458
+ * Recursively walk the AST to infer types for known input variables.
459
+ */
460
+ function inferTypes(node, source, inputs, localScopes, filterCtx = 'none') {
461
+ const { name: nodeName } = node;
462
+ if (nodeName === 'PathExpression') {
463
+ const first = node.firstChild;
464
+ if (first?.name === 'Context' || first?.name === 'PathExpression') {
465
+ inferTypes(first, source, inputs, localScopes, filterCtx);
466
+ return;
467
+ }
468
+ const pathParts = collectPathParts(node, source);
469
+ if (pathParts.length > 0) {
470
+ const rootVar = pathParts[0];
471
+ if (!isInScope(rootVar, localScopes) && !(filterCtx !== 'none' && rootVar === 'item') && findVariable(inputs, rootVar)) {
472
+ buildNestedEntries(inputs, pathParts);
473
+ }
474
+ }
475
+ return;
476
+ }
477
+ if (nodeName === 'Context' && node.parent?.name !== 'List') {
478
+ withScope(localScopes, [], (scope) => {
479
+ forEachChild(node, (child) => {
480
+ if (child.name === 'ContextEntry') {
481
+ forEachChild(child, (innerChild) => {
482
+ if (innerChild.name !== 'Key') {
483
+ inferTypes(innerChild, source, inputs, localScopes, filterCtx);
484
+ }
485
+ });
486
+ const keyName = child.getChild('Key')?.getChild('Name');
487
+ if (keyName)
488
+ scope.add(nodeText(keyName, source));
489
+ }
490
+ });
491
+ });
492
+ return;
493
+ }
494
+ if (nodeName === 'FilterExpression') {
495
+ let newFilterCtx = 'none';
496
+ let listVarName = null;
497
+ const scopeNames = ['item'];
498
+ const listNode = node.getChild('List');
499
+ if (listNode) {
500
+ forEachChild(listNode, (child) => {
501
+ if (child.name === 'Context') {
502
+ scopeNames.push(...extractContextKeys(child, source));
503
+ }
504
+ });
505
+ newFilterCtx = 'list-literal';
506
+ }
507
+ else {
508
+ forEachChild(node, (child) => {
509
+ if (child.name === 'VariableName') {
510
+ listVarName = nodeText(child, source);
511
+ const variable = findVariable(inputs, listVarName);
512
+ if (!isInScope(listVarName, localScopes) && variable) {
513
+ if (!variable.type) {
514
+ variable.type = 'List';
515
+ }
516
+ }
517
+ newFilterCtx = 'variable-list';
518
+ }
519
+ });
520
+ }
521
+ withScope(localScopes, scopeNames, () => {
522
+ forEachChild(node, (child) => {
523
+ if (child.name === 'Comparison' || child.name === 'Expression') {
524
+ trackFilterItemProperties(child, source, listVarName, inputs, localScopes);
525
+ inferTypes(child, source, inputs, localScopes, newFilterCtx);
526
+ }
527
+ });
528
+ });
529
+ return;
530
+ }
531
+ if (nodeName === 'Comparison') {
532
+ const operands = [];
533
+ forEachChild(node, (child) => {
534
+ if (child.name !== 'CompareOp')
535
+ operands.push(child);
536
+ });
537
+ if (operands.length === 2) {
538
+ inferTypeFromComparison(operands[0], operands[1], source, inputs, localScopes);
539
+ inferTypeFromComparison(operands[1], operands[0], source, inputs, localScopes);
540
+ }
541
+ }
542
+ if (nodeName === 'ArithmeticExpression') {
543
+ const { hasString, hasNumber } = checkLiteralsInNode(node);
544
+ const inferredType = hasString && !hasNumber ? 'String'
545
+ : !hasString && hasNumber ? 'Number'
546
+ : null;
547
+ if (inferredType) {
548
+ inferTypeForVariablesInNode(node, source, inputs, localScopes, inferredType);
549
+ }
550
+ forEachChild(node, (child) => {
551
+ if (!['ArithmeticExpression', 'ArithOp', 'NumericLiteral', 'StringLiteral'].includes(child.name)) {
552
+ inferTypes(child, source, inputs, localScopes, filterCtx);
553
+ }
554
+ });
555
+ return;
556
+ }
557
+ if (nodeName === 'ForExpression' || nodeName === 'QuantifiedExpression') {
558
+ const iterVars = collectIterationVariables(node, source);
559
+ const inExp = node.getChild('InExpressions');
560
+ if (inExp) {
561
+ forEachChild(inExp, (child) => {
562
+ if (child.name === 'InExpression') {
563
+ forEachChild(child, (innerChild) => {
564
+ if (!['Name', 'in', 'Identifier'].includes(innerChild.name)) {
565
+ inferTypes(innerChild, source, inputs, localScopes, filterCtx);
566
+ }
567
+ });
568
+ }
569
+ });
570
+ }
571
+ withScope(localScopes, iterVars, () => {
572
+ forEachChild(node, (child) => {
573
+ if (!ITERATION_KEYWORDS.has(child.name)) {
574
+ inferTypes(child, source, inputs, localScopes, 'none');
575
+ }
576
+ });
577
+ });
578
+ return;
579
+ }
580
+ if (nodeName === 'FunctionDefinition') {
581
+ const params = collectFunctionParameters(node, source);
582
+ withScope(localScopes, params, () => {
583
+ const body = node.getChild('FunctionBody');
584
+ if (body)
585
+ inferTypes(body, source, inputs, localScopes, 'none');
586
+ });
587
+ return;
588
+ }
589
+ forEachChild(node, (child) => {
590
+ inferTypes(child, source, inputs, localScopes, filterCtx);
591
+ });
592
+ }
593
+ /**
594
+ * Analyze an AST to extract input variables and infer their types.
595
+ */
596
+ function analyzeForInputs(node, source, builtinNames) {
597
+ const { inputs: collectedInputs, hasErrors } = extractInputNames(node, source, builtinNames);
598
+ const inputs = initializeInputVariables(collectedInputs);
599
+ const localScopes = [new Set()];
600
+ inferTypes(node, source, inputs, localScopes);
601
+ // Sort entries for deterministic output
602
+ for (const variable of inputs) {
603
+ sortEntries(variable);
604
+ }
605
+ inputs.sort((a, b) => a.name.localeCompare(b.name));
606
+ return { inputs, hasErrors };
607
+ }
608
+
609
+ function createContext(variables) {
610
+ return variables.reduce((context, variable) => {
611
+ context[variable.name] = () => { };
612
+ return context;
613
+ }, {});
614
+ }
615
+
616
+ class FeelAnalyzer {
617
+ constructor(options = {}) {
618
+ this.builtinNames = options.builtins?.map((builtin) => builtin.name) ?? [];
619
+ const config = {
620
+ top: options.dialect === 'unaryTests' ? 'UnaryTests' : 'Expression',
621
+ dialect: options.parserDialect,
622
+ };
623
+ if (options.reservedNameBuiltins && options.reservedNameBuiltins.length > 0) {
624
+ config.contextTracker = trackVariables(createContext(options.reservedNameBuiltins));
625
+ }
626
+ this.parser = parser.configure(config);
627
+ }
628
+ analyzeExpression(expression) {
629
+ const tree = this.parser.parse(expression);
630
+ const { inputs, hasErrors } = analyzeForInputs(tree.topNode, expression, new Set(this.builtinNames));
631
+ return {
632
+ valid: !hasErrors,
633
+ inputs,
634
+ };
635
+ }
636
+ }
637
+
638
+ export { FeelAnalyzer };
639
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../src/analyzers/utils.ts","../src/analyzers/inputs.ts","../src/utils/create-context.ts","../src/feel-analyzer.ts"],"sourcesContent":[null,null,null,null],"names":[],"mappings":"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"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Built-in function definition
3
+ */
4
+ export interface Builtin {
5
+ /**
6
+ * Function name
7
+ */
8
+ name: string;
9
+ /**
10
+ * Function type
11
+ */
12
+ type?: 'function';
13
+ /**
14
+ * Function parameters
15
+ */
16
+ params?: Array<{
17
+ name: string;
18
+ }>;
19
+ /**
20
+ * Function documentation
21
+ */
22
+ info?: string;
23
+ }
24
+ /**
25
+ * Input variable information - describes an input variable and its structure.
26
+ * Aligned with the variable-resolver data model.
27
+ */
28
+ export interface InputVariable {
29
+ /**
30
+ * The variable name
31
+ */
32
+ name: string;
33
+ /**
34
+ * The expected type (e.g. 'Context', 'List', 'Number', 'String', 'Boolean').
35
+ * Omitted when the type cannot be inferred.
36
+ */
37
+ type?: string;
38
+ /**
39
+ * For context or list inputs, nested entries describing the structure
40
+ */
41
+ entries?: InputVariable[];
42
+ }
43
+ /**
44
+ * Result of analyzing a FEEL expression
45
+ */
46
+ export interface AnalysisResult {
47
+ /**
48
+ * Whether the expression is valid
49
+ */
50
+ valid: boolean;
51
+ /**
52
+ * Input variables needed by the expression
53
+ */
54
+ inputs?: InputVariable[];
55
+ }
56
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,OAAO;IAEtB;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,IAAI,CAAC,EAAE,UAAU,CAAC;IAElB;;OAEG;IACH,MAAM,CAAC,EAAE,KAAK,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;KACd,CAAC,CAAC;IAEH;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;GAGG;AACH,MAAM,WAAW,aAAa;IAE5B;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,OAAO,CAAC,EAAE,aAAa,EAAE,CAAC;CAC3B;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAE7B;;OAEG;IACH,KAAK,EAAE,OAAO,CAAC;IAEf;;OAEG;IACH,MAAM,CAAC,EAAE,aAAa,EAAE,CAAC;CAC1B"}
@@ -0,0 +1,4 @@
1
+ export declare function createContext(variables: {
2
+ name: string;
3
+ }[]): Record<string, unknown>;
4
+ //# sourceMappingURL=create-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-context.d.ts","sourceRoot":"","sources":["../../src/utils/create-context.ts"],"names":[],"mappings":"AAAA,wBAAgB,aAAa,CAAC,SAAS,EAAE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CASpF"}
package/package.json ADDED
@@ -0,0 +1,73 @@
1
+ {
2
+ "name": "@bpmn-io/feel-analyzer",
3
+ "version": "0.1.0",
4
+ "description": "Static FEEL expression analyzer",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "sideEffects": false,
8
+ "main": "./dist/index.js",
9
+ "module": "./dist/index.js",
10
+ "types": "./dist/index.d.ts",
11
+ "exports": {
12
+ ".": {
13
+ "types": "./dist/index.d.ts",
14
+ "import": "./dist/index.js"
15
+ }
16
+ },
17
+ "files": [
18
+ "dist",
19
+ "package.json"
20
+ ],
21
+ "scripts": {
22
+ "all": "run-s lint test build",
23
+ "lint": "eslint .",
24
+ "test": "mocha --node-option import=tsx test/**/*.spec.ts",
25
+ "build": "rollup -c",
26
+ "prepare": "npm run build"
27
+ },
28
+ "dependencies": {
29
+ "@bpmn-io/lezer-feel": "^2.1.0"
30
+ },
31
+ "devDependencies": {
32
+ "@rollup/plugin-node-resolve": "^16.0.3",
33
+ "@rollup/plugin-typescript": "^12.3.0",
34
+ "@types/chai": "^5.2.3",
35
+ "@types/mocha": "^10.0.10",
36
+ "chai": "^6.2.2",
37
+ "eslint": "^9.39.2",
38
+ "eslint-plugin-bpmn-io": "^2.2.0",
39
+ "mocha": "^11.7.5",
40
+ "npm-run-all2": "^8.0.4",
41
+ "rollup": "^4.57.1",
42
+ "tslib": "^2.8.1",
43
+ "tsx": "^4.21.0",
44
+ "typescript": "^5.9.3",
45
+ "typescript-eslint": "^8.54.0"
46
+ },
47
+ "engines": {
48
+ "node": ">= 20"
49
+ },
50
+ "repository": {
51
+ "type": "git",
52
+ "url": "git+https://github.com/bpmn-io/feel-analyzer.git"
53
+ },
54
+ "homepage": "https://github.com/bpmn-io/feel-analyzer#readme",
55
+ "bugs": {
56
+ "url": "https://github.com/bpmn-io/feel-analyzer/issues"
57
+ },
58
+ "author": {
59
+ "name": "Simon Steinrücken",
60
+ "url": "https://github.com/Buckwich"
61
+ },
62
+ "contributors": [
63
+ {
64
+ "name": "bpmn.io contributors",
65
+ "url": "https://github.com/bpmn-io"
66
+ }
67
+ ],
68
+ "keywords": [
69
+ "feel",
70
+ "bpmn-io",
71
+ "analyzer"
72
+ ]
73
+ }