@jbrowse/jexl 3.0.2 → 3.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/README.md +11 -2
- package/dist/Expression.d.ts +16 -6
- package/dist/Expression.js +34 -8
- package/dist/Expression.js.map +1 -1
- package/dist/Jexl.d.ts +13 -12
- package/dist/Jexl.js +31 -30
- package/dist/Jexl.js.map +1 -1
- package/dist/Lexer.d.ts +9 -8
- package/dist/Lexer.js +58 -18
- package/dist/Lexer.js.map +1 -1
- package/dist/evaluator/Evaluator.d.ts +20 -34
- package/dist/evaluator/Evaluator.js +19 -64
- package/dist/evaluator/Evaluator.js.map +1 -1
- package/dist/evaluator/compile.d.ts +27 -0
- package/dist/evaluator/compile.js +261 -0
- package/dist/evaluator/compile.js.map +1 -0
- package/dist/grammar.d.ts +29 -9
- package/dist/grammar.js +19 -3
- package/dist/grammar.js.map +1 -1
- package/dist/parser/Parser.d.ts +5 -7
- package/dist/parser/Parser.js +17 -2
- package/dist/parser/Parser.js.map +1 -1
- package/dist/parser/handlers.d.ts +0 -6
- package/dist/parser/handlers.js +54 -46
- package/dist/parser/handlers.js.map +1 -1
- package/dist/parser/states.d.ts +2 -2
- package/dist/parser/states.js +0 -20
- package/dist/parser/states.js.map +1 -1
- package/dist/types.d.ts +18 -7
- package/esm/Expression.d.ts +16 -6
- package/esm/Expression.js +34 -8
- package/esm/Expression.js.map +1 -1
- package/esm/Jexl.d.ts +13 -12
- package/esm/Jexl.js +31 -30
- package/esm/Jexl.js.map +1 -1
- package/esm/Lexer.d.ts +9 -8
- package/esm/Lexer.js +58 -18
- package/esm/Lexer.js.map +1 -1
- package/esm/evaluator/Evaluator.d.ts +20 -34
- package/esm/evaluator/Evaluator.js +19 -31
- package/esm/evaluator/Evaluator.js.map +1 -1
- package/esm/evaluator/compile.d.ts +27 -0
- package/esm/evaluator/compile.js +258 -0
- package/esm/evaluator/compile.js.map +1 -0
- package/esm/grammar.d.ts +29 -9
- package/esm/grammar.js +18 -3
- package/esm/grammar.js.map +1 -1
- package/esm/parser/Parser.d.ts +5 -7
- package/esm/parser/Parser.js +17 -2
- package/esm/parser/Parser.js.map +1 -1
- package/esm/parser/handlers.d.ts +0 -6
- package/esm/parser/handlers.js +54 -45
- package/esm/parser/handlers.js.map +1 -1
- package/esm/parser/states.d.ts +2 -2
- package/esm/parser/states.js +0 -20
- package/esm/parser/states.js.map +1 -1
- package/esm/types.d.ts +18 -7
- package/package.json +25 -28
- package/src/Expression.ts +33 -13
- package/src/Jexl.ts +59 -21
- package/src/Lexer.ts +60 -27
- package/src/evaluator/Evaluator.ts +27 -44
- package/src/evaluator/compile.ts +310 -0
- package/src/grammar.ts +66 -17
- package/src/parser/Parser.ts +24 -20
- package/src/parser/handlers.ts +96 -73
- package/src/parser/states.ts +2 -22
- package/src/types.ts +22 -7
- package/CHANGELOG.md +0 -249
- package/dist/evaluator/handlers.d.ts +0 -112
- package/dist/evaluator/handlers.js +0 -208
- package/dist/evaluator/handlers.js.map +0 -1
- package/esm/evaluator/handlers.d.ts +0 -112
- package/esm/evaluator/handlers.js +0 -194
- package/esm/evaluator/handlers.js.map +0 -1
- package/src/evaluator/handlers.ts +0 -212
package/src/parser/handlers.ts
CHANGED
|
@@ -3,7 +3,23 @@
|
|
|
3
3
|
* Copyright 2020 Tom Shawver
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import
|
|
6
|
+
import { precedenceOf } from '../grammar.ts'
|
|
7
|
+
|
|
8
|
+
import type {
|
|
9
|
+
ArrayLiteral,
|
|
10
|
+
AssignmentExpression,
|
|
11
|
+
AstNode,
|
|
12
|
+
BinaryExpression,
|
|
13
|
+
ConditionalExpression,
|
|
14
|
+
FilterExpression,
|
|
15
|
+
FunctionCall,
|
|
16
|
+
Identifier,
|
|
17
|
+
Literal,
|
|
18
|
+
ObjectLiteral,
|
|
19
|
+
TemplateLiteral,
|
|
20
|
+
Token,
|
|
21
|
+
UnaryExpression
|
|
22
|
+
} from '../types.ts'
|
|
7
23
|
import type Parser from './Parser.ts'
|
|
8
24
|
|
|
9
25
|
/**
|
|
@@ -12,7 +28,7 @@ import type Parser from './Parser.ts'
|
|
|
12
28
|
*/
|
|
13
29
|
export function argVal(this: Parser, ast: AstNode | null) {
|
|
14
30
|
if (ast) {
|
|
15
|
-
;(this._cursor as
|
|
31
|
+
;(this._cursor as FunctionCall).args.push(ast)
|
|
16
32
|
}
|
|
17
33
|
}
|
|
18
34
|
|
|
@@ -21,10 +37,11 @@ export function argVal(this: Parser, ast: AstNode | null) {
|
|
|
21
37
|
* initialized with an empty array.
|
|
22
38
|
*/
|
|
23
39
|
export function arrayStart(this: Parser) {
|
|
24
|
-
|
|
40
|
+
const node: ArrayLiteral = {
|
|
25
41
|
type: 'ArrayLiteral',
|
|
26
42
|
value: []
|
|
27
|
-
}
|
|
43
|
+
}
|
|
44
|
+
this._placeAtCursor(node)
|
|
28
45
|
}
|
|
29
46
|
|
|
30
47
|
/**
|
|
@@ -33,7 +50,7 @@ export function arrayStart(this: Parser) {
|
|
|
33
50
|
*/
|
|
34
51
|
export function arrayVal(this: Parser, ast: AstNode | null) {
|
|
35
52
|
if (ast) {
|
|
36
|
-
;(this._cursor as
|
|
53
|
+
;(this._cursor as ArrayLiteral).value.push(ast)
|
|
37
54
|
}
|
|
38
55
|
}
|
|
39
56
|
|
|
@@ -44,34 +61,45 @@ export function arrayVal(this: Parser, ast: AstNode | null) {
|
|
|
44
61
|
*/
|
|
45
62
|
export function binaryOp(this: Parser, token: Token) {
|
|
46
63
|
if (token.value === '=') {
|
|
47
|
-
|
|
64
|
+
// `from` marks a member access such as `a.b`; only a bare name can be
|
|
65
|
+
// assigned to, since the Evaluator writes straight into the context
|
|
66
|
+
if (
|
|
67
|
+
this._cursor?.type !== 'Identifier' ||
|
|
68
|
+
(this._cursor as Identifier).from
|
|
69
|
+
) {
|
|
48
70
|
throw new Error('Left side of assignment must be a variable name')
|
|
49
71
|
}
|
|
50
72
|
|
|
51
|
-
const node:
|
|
73
|
+
const node: AssignmentExpression = {
|
|
52
74
|
type: 'AssignmentExpression',
|
|
53
75
|
operator: '=',
|
|
54
|
-
left: this._cursor
|
|
76
|
+
left: this._cursor as Identifier
|
|
55
77
|
}
|
|
56
78
|
this._cursor = this._cursor._parent
|
|
57
79
|
this._placeAtCursor(node)
|
|
58
80
|
return
|
|
59
81
|
}
|
|
60
82
|
|
|
61
|
-
const
|
|
83
|
+
const tokenValue = token.value as string
|
|
84
|
+
const precedence = precedenceOf(this._grammar.elements[tokenValue])
|
|
62
85
|
let parent = this._cursor?._parent
|
|
63
|
-
while (
|
|
64
|
-
parent
|
|
65
|
-
(
|
|
66
|
-
|
|
67
|
-
|
|
86
|
+
while (parent) {
|
|
87
|
+
const parentExpr = parent as BinaryExpression
|
|
88
|
+
if (!parentExpr.operator) {
|
|
89
|
+
break
|
|
90
|
+
}
|
|
91
|
+
if (
|
|
92
|
+
precedenceOf(this._grammar.elements[parentExpr.operator]) < precedence
|
|
93
|
+
) {
|
|
94
|
+
break
|
|
95
|
+
}
|
|
68
96
|
this._cursor = parent
|
|
69
97
|
parent = parent._parent
|
|
70
98
|
}
|
|
71
|
-
const node:
|
|
99
|
+
const node: BinaryExpression = {
|
|
72
100
|
type: 'BinaryExpression',
|
|
73
|
-
operator:
|
|
74
|
-
left: this._cursor
|
|
101
|
+
operator: tokenValue,
|
|
102
|
+
left: this._cursor!
|
|
75
103
|
}
|
|
76
104
|
this._setParent(this._cursor!, node)
|
|
77
105
|
this._cursor = parent
|
|
@@ -84,16 +112,16 @@ export function binaryOp(this: Parser, token: Token) {
|
|
|
84
112
|
* AST.
|
|
85
113
|
*/
|
|
86
114
|
export function dot(this: Parser) {
|
|
87
|
-
const
|
|
88
|
-
|
|
89
|
-
|
|
115
|
+
const cursor = this._cursor
|
|
116
|
+
// the dot continues an identifier chain unless the cursor is an operator
|
|
117
|
+
// still waiting on its right-hand side, in which case it opens a relative
|
|
118
|
+
// path instead — as in the leading dot of `list[.price > 5]`
|
|
90
119
|
this._nextIdentEncapsulate =
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
(
|
|
94
|
-
isBinaryExprWithRight(this._cursor))
|
|
120
|
+
!!cursor &&
|
|
121
|
+
cursor.type !== 'UnaryExpression' &&
|
|
122
|
+
(cursor.type !== 'BinaryExpression' || !!cursor.right)
|
|
95
123
|
|
|
96
|
-
this._nextIdentRelative = !this.
|
|
124
|
+
this._nextIdentRelative = !this._nextIdentEncapsulate
|
|
97
125
|
if (this._nextIdentRelative) {
|
|
98
126
|
this._relative = true
|
|
99
127
|
}
|
|
@@ -105,12 +133,13 @@ export function dot(this: Parser) {
|
|
|
105
133
|
* @param {{type: <string>}} ast The subexpression tree
|
|
106
134
|
*/
|
|
107
135
|
export function filter(this: Parser, ast: AstNode | null) {
|
|
108
|
-
|
|
136
|
+
const node: FilterExpression = {
|
|
109
137
|
type: 'FilterExpression',
|
|
110
|
-
expr: ast
|
|
138
|
+
expr: ast!,
|
|
111
139
|
relative: this._subParser!.isRelative(),
|
|
112
|
-
subject: this._cursor
|
|
113
|
-
}
|
|
140
|
+
subject: this._cursor!
|
|
141
|
+
}
|
|
142
|
+
this._placeBeforeCursor(node)
|
|
114
143
|
}
|
|
115
144
|
|
|
116
145
|
/**
|
|
@@ -119,12 +148,13 @@ export function filter(this: Parser, ast: AstNode | null) {
|
|
|
119
148
|
* @param {{type: <string>}} token A token object
|
|
120
149
|
*/
|
|
121
150
|
export function functionCall(this: Parser) {
|
|
122
|
-
|
|
151
|
+
const node: FunctionCall = {
|
|
123
152
|
type: 'FunctionCall',
|
|
124
|
-
name: (this._cursor as
|
|
153
|
+
name: (this._cursor as Identifier).value,
|
|
125
154
|
args: [],
|
|
126
155
|
pool: 'functions'
|
|
127
|
-
}
|
|
156
|
+
}
|
|
157
|
+
this._placeBeforeCursor(node)
|
|
128
158
|
}
|
|
129
159
|
|
|
130
160
|
/**
|
|
@@ -132,12 +162,12 @@ export function functionCall(this: Parser) {
|
|
|
132
162
|
* @param {{type: <string>}} token A token object
|
|
133
163
|
*/
|
|
134
164
|
export function identifier(this: Parser, token: Token) {
|
|
135
|
-
const node:
|
|
165
|
+
const node: Identifier = {
|
|
136
166
|
type: 'Identifier',
|
|
137
|
-
value: token.value
|
|
167
|
+
value: token.value as string
|
|
138
168
|
}
|
|
139
169
|
if (this._nextIdentEncapsulate) {
|
|
140
|
-
node.from = this._cursor
|
|
170
|
+
node.from = this._cursor!
|
|
141
171
|
this._placeBeforeCursor(node)
|
|
142
172
|
this._nextIdentEncapsulate = false
|
|
143
173
|
} else {
|
|
@@ -155,10 +185,11 @@ export function identifier(this: Parser, token: Token) {
|
|
|
155
185
|
* @param {{type: <string>}} token A token object
|
|
156
186
|
*/
|
|
157
187
|
export function literal(this: Parser, token: Token) {
|
|
158
|
-
|
|
188
|
+
const node: Literal = {
|
|
159
189
|
type: 'Literal',
|
|
160
|
-
value: token.value
|
|
161
|
-
}
|
|
190
|
+
value: token.value as string | number | boolean
|
|
191
|
+
}
|
|
192
|
+
this._placeAtCursor(node)
|
|
162
193
|
}
|
|
163
194
|
|
|
164
195
|
/**
|
|
@@ -167,9 +198,10 @@ export function literal(this: Parser, token: Token) {
|
|
|
167
198
|
* @param {{type: <string>}} token A token object
|
|
168
199
|
*/
|
|
169
200
|
export function templateString(this: Parser, token: Token) {
|
|
170
|
-
const parts:
|
|
201
|
+
const parts: TemplateLiteral['parts'] = []
|
|
202
|
+
const tokenParts = Array.isArray(token.value) ? token.value : []
|
|
171
203
|
|
|
172
|
-
for (const part of
|
|
204
|
+
for (const part of tokenParts) {
|
|
173
205
|
if (part.type === 'static') {
|
|
174
206
|
parts.push({
|
|
175
207
|
type: 'static',
|
|
@@ -177,10 +209,11 @@ export function templateString(this: Parser, token: Token) {
|
|
|
177
209
|
})
|
|
178
210
|
} else {
|
|
179
211
|
const subTokens = this._lexer.tokenize(part.value)
|
|
180
|
-
const
|
|
181
|
-
this._grammar,
|
|
182
|
-
this._lexer
|
|
183
|
-
)
|
|
212
|
+
const ParserClass = this.constructor as new (
|
|
213
|
+
grammar: typeof this._grammar,
|
|
214
|
+
lexer: typeof this._lexer
|
|
215
|
+
) => Parser
|
|
216
|
+
const subParser = new ParserClass(this._grammar, this._lexer)
|
|
184
217
|
subParser.addTokens(subTokens)
|
|
185
218
|
const subAst = subParser.complete()
|
|
186
219
|
|
|
@@ -195,10 +228,11 @@ export function templateString(this: Parser, token: Token) {
|
|
|
195
228
|
}
|
|
196
229
|
}
|
|
197
230
|
|
|
198
|
-
|
|
231
|
+
const node: TemplateLiteral = {
|
|
199
232
|
type: 'TemplateLiteral',
|
|
200
|
-
parts
|
|
201
|
-
}
|
|
233
|
+
parts
|
|
234
|
+
}
|
|
235
|
+
this._placeAtCursor(node)
|
|
202
236
|
}
|
|
203
237
|
|
|
204
238
|
/**
|
|
@@ -206,7 +240,7 @@ export function templateString(this: Parser, token: Token) {
|
|
|
206
240
|
* @param {{type: <string>}} token A token object
|
|
207
241
|
*/
|
|
208
242
|
export function objKey(this: Parser, token: Token) {
|
|
209
|
-
this._curObjKey = token.value
|
|
243
|
+
this._curObjKey = token.value as string
|
|
210
244
|
}
|
|
211
245
|
|
|
212
246
|
/**
|
|
@@ -214,10 +248,11 @@ export function objKey(this: Parser, token: Token) {
|
|
|
214
248
|
* initialized with an empty object.
|
|
215
249
|
*/
|
|
216
250
|
export function objStart(this: Parser) {
|
|
217
|
-
|
|
251
|
+
const node: ObjectLiteral = {
|
|
218
252
|
type: 'ObjectLiteral',
|
|
219
253
|
value: {}
|
|
220
|
-
}
|
|
254
|
+
}
|
|
255
|
+
this._placeAtCursor(node)
|
|
221
256
|
}
|
|
222
257
|
|
|
223
258
|
/**
|
|
@@ -226,7 +261,7 @@ export function objStart(this: Parser) {
|
|
|
226
261
|
* @param {{type: <string>}} ast The subexpression tree
|
|
227
262
|
*/
|
|
228
263
|
export function objVal(this: Parser, ast: AstNode | null) {
|
|
229
|
-
;(this._cursor as
|
|
264
|
+
;(this._cursor as ObjectLiteral).value[this._curObjKey!] = ast!
|
|
230
265
|
}
|
|
231
266
|
|
|
232
267
|
/**
|
|
@@ -243,7 +278,7 @@ export function subExpression(this: Parser, ast: AstNode | null) {
|
|
|
243
278
|
* @param {{type: <string>}} ast The subexpression tree
|
|
244
279
|
*/
|
|
245
280
|
export function ternaryEnd(this: Parser, ast: AstNode | null) {
|
|
246
|
-
;(this._cursor as
|
|
281
|
+
;(this._cursor as ConditionalExpression).alternate = ast ?? undefined
|
|
247
282
|
}
|
|
248
283
|
|
|
249
284
|
/**
|
|
@@ -251,7 +286,7 @@ export function ternaryEnd(this: Parser, ast: AstNode | null) {
|
|
|
251
286
|
* @param {{type: <string>}} ast The subexpression tree
|
|
252
287
|
*/
|
|
253
288
|
export function ternaryMid(this: Parser, ast: AstNode | null) {
|
|
254
|
-
;(this._cursor as
|
|
289
|
+
;(this._cursor as ConditionalExpression).consequent = ast ?? undefined
|
|
255
290
|
}
|
|
256
291
|
|
|
257
292
|
/**
|
|
@@ -260,37 +295,25 @@ export function ternaryMid(this: Parser, ast: AstNode | null) {
|
|
|
260
295
|
* test element.
|
|
261
296
|
*/
|
|
262
297
|
export function ternaryStart(this: Parser) {
|
|
263
|
-
|
|
298
|
+
const node: ConditionalExpression = {
|
|
264
299
|
type: 'ConditionalExpression',
|
|
265
|
-
test: this._tree
|
|
266
|
-
}
|
|
300
|
+
test: this._tree!
|
|
301
|
+
}
|
|
302
|
+
this._tree = node
|
|
267
303
|
this._cursor = this._tree
|
|
268
304
|
}
|
|
269
305
|
|
|
270
|
-
/**
|
|
271
|
-
* Handles identifier tokens when used to indicate the name of a transform to
|
|
272
|
-
* be applied.
|
|
273
|
-
* @param {{type: <string>}} token A token object
|
|
274
|
-
*/
|
|
275
|
-
export function transform(this: Parser, token: Token) {
|
|
276
|
-
this._placeBeforeCursor({
|
|
277
|
-
type: 'FunctionCall',
|
|
278
|
-
name: token.value,
|
|
279
|
-
args: [this._cursor],
|
|
280
|
-
pool: 'transforms'
|
|
281
|
-
} as any)
|
|
282
|
-
}
|
|
283
|
-
|
|
284
306
|
/**
|
|
285
307
|
* Handles token of type 'unaryOp', indicating that the operation has only
|
|
286
308
|
* one input: a right side.
|
|
287
309
|
* @param {{type: <string>}} token A token object
|
|
288
310
|
*/
|
|
289
311
|
export function unaryOp(this: Parser, token: Token) {
|
|
290
|
-
|
|
312
|
+
const node: UnaryExpression = {
|
|
291
313
|
type: 'UnaryExpression',
|
|
292
|
-
operator: token.value
|
|
293
|
-
}
|
|
314
|
+
operator: token.value as string
|
|
315
|
+
}
|
|
316
|
+
this._placeAtCursor(node)
|
|
294
317
|
}
|
|
295
318
|
|
|
296
319
|
/**
|
package/src/parser/states.ts
CHANGED
|
@@ -5,12 +5,12 @@
|
|
|
5
5
|
|
|
6
6
|
import * as h from './handlers.ts'
|
|
7
7
|
|
|
8
|
-
import type { AstNode } from '../types.ts'
|
|
8
|
+
import type { AstNode, Token } from '../types.ts'
|
|
9
9
|
import type Parser from './Parser.ts'
|
|
10
10
|
|
|
11
11
|
interface TokenTypeOptions {
|
|
12
12
|
toState?: string
|
|
13
|
-
handler?: (this: Parser,
|
|
13
|
+
handler?: (this: Parser, token: Token) => void
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
interface StateDefinition {
|
|
@@ -70,7 +70,6 @@ export const states: States = {
|
|
|
70
70
|
expectBinOp: {
|
|
71
71
|
tokenTypes: {
|
|
72
72
|
binaryOp: { toState: 'expectOperand' },
|
|
73
|
-
pipe: { toState: 'expectTransform' },
|
|
74
73
|
dot: { toState: 'traverse' },
|
|
75
74
|
openBracket: { toState: 'filter' },
|
|
76
75
|
question: { toState: 'ternaryMid', handler: h.ternaryStart },
|
|
@@ -78,11 +77,6 @@ export const states: States = {
|
|
|
78
77
|
},
|
|
79
78
|
completable: true
|
|
80
79
|
},
|
|
81
|
-
expectTransform: {
|
|
82
|
-
tokenTypes: {
|
|
83
|
-
identifier: { toState: 'postTransform', handler: h.transform }
|
|
84
|
-
}
|
|
85
|
-
},
|
|
86
80
|
expectObjKey: {
|
|
87
81
|
tokenTypes: {
|
|
88
82
|
literal: { toState: 'expectKeyValSep', handler: h.objKey },
|
|
@@ -95,24 +89,11 @@ export const states: States = {
|
|
|
95
89
|
colon: { toState: 'objVal' }
|
|
96
90
|
}
|
|
97
91
|
},
|
|
98
|
-
postTransform: {
|
|
99
|
-
tokenTypes: {
|
|
100
|
-
openParen: { toState: 'argVal' },
|
|
101
|
-
binaryOp: { toState: 'expectOperand' },
|
|
102
|
-
dot: { toState: 'traverse' },
|
|
103
|
-
openBracket: { toState: 'filter' },
|
|
104
|
-
pipe: { toState: 'expectTransform' },
|
|
105
|
-
question: { toState: 'ternaryMid', handler: h.ternaryStart },
|
|
106
|
-
semicolon: { handler: h.semicolon }
|
|
107
|
-
},
|
|
108
|
-
completable: true
|
|
109
|
-
},
|
|
110
92
|
postArgs: {
|
|
111
93
|
tokenTypes: {
|
|
112
94
|
binaryOp: { toState: 'expectOperand' },
|
|
113
95
|
dot: { toState: 'traverse' },
|
|
114
96
|
openBracket: { toState: 'filter' },
|
|
115
|
-
pipe: { toState: 'expectTransform' },
|
|
116
97
|
question: { toState: 'ternaryMid', handler: h.ternaryStart },
|
|
117
98
|
semicolon: { handler: h.semicolon }
|
|
118
99
|
},
|
|
@@ -124,7 +105,6 @@ export const states: States = {
|
|
|
124
105
|
dot: { toState: 'traverse' },
|
|
125
106
|
openBracket: { toState: 'filter' },
|
|
126
107
|
openParen: { toState: 'argVal', handler: h.functionCall },
|
|
127
|
-
pipe: { toState: 'expectTransform' },
|
|
128
108
|
question: { toState: 'ternaryMid', handler: h.ternaryStart },
|
|
129
109
|
semicolon: { handler: h.semicolon }
|
|
130
110
|
},
|
package/src/types.ts
CHANGED
|
@@ -3,15 +3,30 @@
|
|
|
3
3
|
* Copyright 2020 Tom Shawver
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
+
export interface TemplatePart {
|
|
7
|
+
type: 'static' | 'interpolation'
|
|
8
|
+
value: string
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export type JexlValue =
|
|
12
|
+
| string
|
|
13
|
+
| number
|
|
14
|
+
| boolean
|
|
15
|
+
| null
|
|
16
|
+
| undefined
|
|
17
|
+
| JexlValue[]
|
|
18
|
+
| { [key: string]: JexlValue }
|
|
19
|
+
|
|
6
20
|
export interface Token {
|
|
7
21
|
type: string
|
|
8
|
-
value:
|
|
22
|
+
value: string | number | boolean | TemplatePart[]
|
|
9
23
|
raw: string
|
|
10
24
|
}
|
|
11
25
|
|
|
12
26
|
export interface AstNode {
|
|
13
27
|
type: string
|
|
14
28
|
_parent?: AstNode
|
|
29
|
+
right?: AstNode
|
|
15
30
|
}
|
|
16
31
|
|
|
17
32
|
export interface Literal extends AstNode {
|
|
@@ -49,19 +64,20 @@ export interface ObjectLiteral extends AstNode {
|
|
|
49
64
|
value: Record<string, AstNode>
|
|
50
65
|
}
|
|
51
66
|
|
|
67
|
+
export type TemplateLiteralPart =
|
|
68
|
+
| { type: 'static'; value: string }
|
|
69
|
+
| { type: 'expression'; value: AstNode }
|
|
70
|
+
|
|
52
71
|
export interface TemplateLiteral extends AstNode {
|
|
53
72
|
type: 'TemplateLiteral'
|
|
54
|
-
parts:
|
|
55
|
-
type: 'static' | 'expression'
|
|
56
|
-
value: string | AstNode
|
|
57
|
-
}[]
|
|
73
|
+
parts: TemplateLiteralPart[]
|
|
58
74
|
}
|
|
59
75
|
|
|
60
76
|
export interface FunctionCall extends AstNode {
|
|
61
77
|
type: 'FunctionCall'
|
|
62
78
|
name: string
|
|
63
79
|
args: AstNode[]
|
|
64
|
-
pool: 'functions'
|
|
80
|
+
pool: 'functions'
|
|
65
81
|
}
|
|
66
82
|
|
|
67
83
|
export interface FilterExpression extends AstNode {
|
|
@@ -87,7 +103,6 @@ export interface AssignmentExpression extends AstNode {
|
|
|
87
103
|
type: 'AssignmentExpression'
|
|
88
104
|
operator: '='
|
|
89
105
|
left: Identifier
|
|
90
|
-
right: AstNode
|
|
91
106
|
}
|
|
92
107
|
|
|
93
108
|
export type AstNodeUnion =
|