flowquery 1.0.14 → 1.0.15

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.
Files changed (55) hide show
  1. package/.editorconfig +21 -0
  2. package/.husky/pre-commit +1 -0
  3. package/.prettierrc +22 -0
  4. package/dist/flowquery.min.js +1 -1
  5. package/dist/parsing/expressions/expression_map.d.ts +8 -0
  6. package/dist/parsing/expressions/expression_map.d.ts.map +1 -0
  7. package/dist/parsing/expressions/expression_map.js +21 -0
  8. package/dist/parsing/expressions/expression_map.js.map +1 -0
  9. package/dist/parsing/operations/call.d.ts +17 -0
  10. package/dist/parsing/operations/call.d.ts.map +1 -0
  11. package/dist/parsing/operations/call.js +103 -0
  12. package/dist/parsing/operations/call.js.map +1 -0
  13. package/dist/parsing/operations/load.d.ts +6 -6
  14. package/dist/parsing/operations/load.d.ts.map +1 -1
  15. package/dist/parsing/operations/load.js +8 -6
  16. package/dist/parsing/operations/load.js.map +1 -1
  17. package/dist/parsing/operations/operation.d.ts +1 -0
  18. package/dist/parsing/operations/operation.d.ts.map +1 -1
  19. package/dist/parsing/operations/operation.js +6 -5
  20. package/dist/parsing/operations/operation.js.map +1 -1
  21. package/dist/parsing/operations/projection.d.ts +1 -1
  22. package/dist/parsing/operations/projection.d.ts.map +1 -1
  23. package/dist/parsing/operations/projection.js.map +1 -1
  24. package/dist/parsing/parser.d.ts +1 -0
  25. package/dist/parsing/parser.d.ts.map +1 -1
  26. package/dist/parsing/parser.js +148 -99
  27. package/dist/parsing/parser.js.map +1 -1
  28. package/dist/parsing/token_to_node.d.ts +2 -2
  29. package/dist/parsing/token_to_node.d.ts.map +1 -1
  30. package/dist/parsing/token_to_node.js +12 -12
  31. package/dist/parsing/token_to_node.js.map +1 -1
  32. package/dist/tokenization/token.d.ts +5 -1
  33. package/dist/tokenization/token.d.ts.map +1 -1
  34. package/dist/tokenization/token.js +17 -5
  35. package/dist/tokenization/token.js.map +1 -1
  36. package/docs/flowquery.min.js +1 -1
  37. package/flowquery-vscode/flowQueryEngine/flowquery.min.js +1 -1
  38. package/misc/apps/RAG/package.json +1 -1
  39. package/misc/apps/RAG/src/plugins/loaders/FetchJson.ts +66 -0
  40. package/misc/apps/RAG/src/plugins/loaders/Llm.ts +4 -3
  41. package/misc/apps/RAG/src/plugins/loaders/MockData.ts +7 -5
  42. package/misc/apps/RAG/src/plugins/loaders/Table.ts +3 -3
  43. package/misc/apps/RAG/src/plugins/loaders/Weather.ts +4 -3
  44. package/package.json +12 -2
  45. package/src/parsing/expressions/expression_map.ts +19 -0
  46. package/src/parsing/operations/call.ts +67 -0
  47. package/src/parsing/operations/load.ts +123 -120
  48. package/src/parsing/operations/operation.ts +14 -13
  49. package/src/parsing/operations/projection.ts +3 -3
  50. package/src/parsing/parser.ts +303 -239
  51. package/src/parsing/token_to_node.ts +67 -50
  52. package/src/tokenization/token.ts +29 -14
  53. package/tests/compute/runner.test.ts +277 -165
  54. package/tests/parsing/parser.test.ts +355 -303
  55. package/vscode-settings.json.recommended +16 -0
@@ -1,213 +1,270 @@
1
- import Runner from '../../src/compute/runner';
1
+ import Runner from "../../src/compute/runner";
2
+ import AsyncFunction from "../../src/parsing/functions/async_function";
3
+ import { FunctionDef } from "../../src/parsing/functions/function_metadata";
2
4
 
3
- test('Test return', async () => {
4
- const runner = new Runner('return 1 + 2 as sum');
5
+ // Test classes for CALL operation tests - defined at module level for Prettier compatibility
6
+ @FunctionDef({
7
+ description: "Asynchronous function for testing CALL operation",
8
+ category: "async",
9
+ parameters: [],
10
+ output: { description: "Yields test values", type: "any" },
11
+ })
12
+ class CallTestFunction extends AsyncFunction {
13
+ constructor() {
14
+ super();
15
+ this._expectedParameterCount = 0;
16
+ }
17
+ public async *generate(): AsyncGenerator<any> {
18
+ yield { result: 1 };
19
+ yield { result: 2 };
20
+ yield { result: 3 };
21
+ }
22
+ }
23
+
24
+ @FunctionDef({
25
+ description: "Asynchronous function for testing CALL operation with no yielded expressions",
26
+ category: "async",
27
+ parameters: [],
28
+ output: { description: "Yields test values", type: "any" },
29
+ })
30
+ class CallTestFunctionNoObject extends AsyncFunction {
31
+ constructor() {
32
+ super();
33
+ this._expectedParameterCount = 0;
34
+ }
35
+ public async *generate(): AsyncGenerator<any> {
36
+ yield 1;
37
+ yield 2;
38
+ yield 3;
39
+ }
40
+ }
41
+
42
+ test("Test return", async () => {
43
+ const runner = new Runner("return 1 + 2 as sum");
5
44
  await runner.run();
6
45
  const results = runner.results;
7
46
  expect(results.length).toBe(1);
8
- expect(results[0]).toEqual({'sum': 3});
47
+ expect(results[0]).toEqual({ sum: 3 });
9
48
  });
10
49
 
11
- test('Test return with multiple expressions', async () => {
12
- const runner = new Runner('return 1 + 2 as sum, 3 + 4 as sum2');
50
+ test("Test return with multiple expressions", async () => {
51
+ const runner = new Runner("return 1 + 2 as sum, 3 + 4 as sum2");
13
52
  await runner.run();
14
53
  const results = runner.results;
15
54
  expect(results.length).toBe(1);
16
- expect(results[0]).toEqual({'sum': 3, 'sum2': 7});
55
+ expect(results[0]).toEqual({ sum: 3, sum2: 7 });
17
56
  });
18
57
 
19
- test('Test unwind and return', async () => {
20
- const runner = new Runner('unwind [1, 2, 3] as num return num');
58
+ test("Test unwind and return", async () => {
59
+ const runner = new Runner("unwind [1, 2, 3] as num return num");
21
60
  await runner.run();
22
61
  const results = runner.results;
23
62
  expect(results.length).toBe(3);
24
- expect(results[0]).toEqual({'num': 1});
25
- expect(results[1]).toEqual({'num': 2});
26
- expect(results[2]).toEqual({'num': 3});
63
+ expect(results[0]).toEqual({ num: 1 });
64
+ expect(results[1]).toEqual({ num: 2 });
65
+ expect(results[2]).toEqual({ num: 3 });
27
66
  });
28
67
 
29
- test('Test load and return', async () => {
30
- const runner = new Runner('load json from "https://jsonplaceholder.typicode.com/todos" as todo return todo');
68
+ test("Test load and return", async () => {
69
+ const runner = new Runner(
70
+ 'load json from "https://jsonplaceholder.typicode.com/todos" as todo return todo'
71
+ );
31
72
  await runner.run();
32
73
  const results = runner.results;
33
74
  expect(results.length).toBeGreaterThan(0);
34
75
  });
35
76
 
36
- test('Test load with post and return', async () => {
37
- const runner = new Runner('load json from "https://jsonplaceholder.typicode.com/posts" post {userId: 1} as data return data');
77
+ test("Test load with post and return", async () => {
78
+ const runner = new Runner(
79
+ 'load json from "https://jsonplaceholder.typicode.com/posts" post {userId: 1} as data return data'
80
+ );
38
81
  await runner.run();
39
82
  const results = runner.results;
40
83
  expect(results.length).toBe(1);
41
84
  });
42
85
 
43
- test('Test aggregated return', async () => {
44
- const runner = new Runner('unwind [1, 1, 2, 2] as i unwind [1, 2, 3, 4] as j return i, sum(j) as sum');
86
+ test("Test aggregated return", async () => {
87
+ const runner = new Runner(
88
+ "unwind [1, 1, 2, 2] as i unwind [1, 2, 3, 4] as j return i, sum(j) as sum"
89
+ );
45
90
  await runner.run();
46
91
  const results = runner.results;
47
92
  expect(results.length).toBe(2);
48
- expect(results[0]).toEqual({'i': 1, 'sum': 20});
49
- expect(results[1]).toEqual({'i': 2, 'sum': 20});
93
+ expect(results[0]).toEqual({ i: 1, sum: 20 });
94
+ expect(results[1]).toEqual({ i: 2, sum: 20 });
50
95
  });
51
96
 
52
- test('Test aggregated return with string', async () => {
53
- const runner = new Runner('unwind [1, 1, 2, 2] as i unwind ["a", "b", "c", "d"] as j return i, sum(j) as sum');
97
+ test("Test aggregated return with string", async () => {
98
+ const runner = new Runner(
99
+ 'unwind [1, 1, 2, 2] as i unwind ["a", "b", "c", "d"] as j return i, sum(j) as sum'
100
+ );
54
101
  await runner.run();
55
102
  const results = runner.results;
56
103
  expect(results.length).toBe(2);
57
- expect(results[0]).toEqual({'i': 1, 'sum': 'abcdabcd'});
58
- expect(results[1]).toEqual({'i': 2, 'sum': 'abcdabcd'});
104
+ expect(results[0]).toEqual({ i: 1, sum: "abcdabcd" });
105
+ expect(results[1]).toEqual({ i: 2, sum: "abcdabcd" });
59
106
  });
60
107
 
61
- test('Test aggregated return with object', async () => {
62
- const runner = new Runner('unwind [1, 1, 2, 2] as i unwind [1, 2, 3 4] as j return i, {sum: sum(j)} as sum');
108
+ test("Test aggregated return with object", async () => {
109
+ const runner = new Runner(
110
+ "unwind [1, 1, 2, 2] as i unwind [1, 2, 3 4] as j return i, {sum: sum(j)} as sum"
111
+ );
63
112
  await runner.run();
64
113
  const results = runner.results;
65
114
  expect(results.length).toBe(2);
66
- expect(results[0]).toEqual({'i': 1, 'sum': {'sum': 20}});
67
- expect(results[1]).toEqual({'i': 2, 'sum': {'sum': 20}});
115
+ expect(results[0]).toEqual({ i: 1, sum: { sum: 20 } });
116
+ expect(results[1]).toEqual({ i: 2, sum: { sum: 20 } });
68
117
  });
69
118
 
70
- test('Test aggregated return with array', async () => {
71
- const runner = new Runner('unwind [1, 1, 2, 2] as i unwind [1, 2, 3 4] as j return i, [sum(j)] as sum');
119
+ test("Test aggregated return with array", async () => {
120
+ const runner = new Runner(
121
+ "unwind [1, 1, 2, 2] as i unwind [1, 2, 3 4] as j return i, [sum(j)] as sum"
122
+ );
72
123
  await runner.run();
73
124
  const results = runner.results;
74
125
  expect(results.length).toBe(2);
75
- expect(results[0]).toEqual({'i': 1, 'sum': [20]});
76
- expect(results[1]).toEqual({'i': 2, 'sum': [20]});
126
+ expect(results[0]).toEqual({ i: 1, sum: [20] });
127
+ expect(results[1]).toEqual({ i: 2, sum: [20] });
77
128
  });
78
129
 
79
- test('Test aggregated return with multiple aggregates', async () => {
80
- const runner = new Runner('unwind [1, 1, 2, 2] as i unwind [1, 2, 3, 4] as j return i, sum(j) as sum, avg(j) as avg');
130
+ test("Test aggregated return with multiple aggregates", async () => {
131
+ const runner = new Runner(
132
+ "unwind [1, 1, 2, 2] as i unwind [1, 2, 3, 4] as j return i, sum(j) as sum, avg(j) as avg"
133
+ );
81
134
  await runner.run();
82
135
  const results = runner.results;
83
136
  expect(results.length).toBe(2);
84
- expect(results[0]).toEqual({'i': 1, 'sum': 20, 'avg': 2.5});
85
- expect(results[1]).toEqual({'i': 2, 'sum': 20, 'avg': 2.5});
137
+ expect(results[0]).toEqual({ i: 1, sum: 20, avg: 2.5 });
138
+ expect(results[1]).toEqual({ i: 2, sum: 20, avg: 2.5 });
86
139
  });
87
140
 
88
- test('Test avg with null', async () => {
89
- const runner = new Runner('return avg(null) as avg');
141
+ test("Test avg with null", async () => {
142
+ const runner = new Runner("return avg(null) as avg");
90
143
  await runner.run();
91
144
  const results = runner.results;
92
145
  expect(results.length).toBe(1);
93
- expect(results[0]).toEqual({'avg': null});
146
+ expect(results[0]).toEqual({ avg: null });
94
147
  });
95
148
 
96
- test('Test sum with null', async () => {
97
- const runner = new Runner('return sum(null) as sum');
149
+ test("Test sum with null", async () => {
150
+ const runner = new Runner("return sum(null) as sum");
98
151
  await runner.run();
99
152
  const results = runner.results;
100
153
  expect(results.length).toBe(1);
101
- expect(results[0]).toEqual({'sum': null});
154
+ expect(results[0]).toEqual({ sum: null });
102
155
  });
103
156
 
104
- test('Test avg with one value', async () => {
105
- const runner = new Runner('return avg(1) as avg');
157
+ test("Test avg with one value", async () => {
158
+ const runner = new Runner("return avg(1) as avg");
106
159
  await runner.run();
107
160
  const results = runner.results;
108
161
  expect(results.length).toBe(1);
109
- expect(results[0]).toEqual({'avg': 1});
162
+ expect(results[0]).toEqual({ avg: 1 });
110
163
  });
111
164
 
112
- test('Test with and return', async () => {
113
- const runner = new Runner('with 1 as a return a');
165
+ test("Test with and return", async () => {
166
+ const runner = new Runner("with 1 as a return a");
114
167
  await runner.run();
115
168
  const results = runner.results;
116
169
  expect(results.length).toBe(1);
117
- expect(results[0]).toEqual({'a': 1});
170
+ expect(results[0]).toEqual({ a: 1 });
118
171
  });
119
172
 
120
- test('Test nested aggregate functions', async () => {
173
+ test("Test nested aggregate functions", async () => {
121
174
  expect(() => {
122
- new Runner('unwind [1, 2, 3, 4] as i return sum(sum(i)) as sum')
123
- }).toThrow('Aggregate functions cannot be nested');
175
+ new Runner("unwind [1, 2, 3, 4] as i return sum(sum(i)) as sum");
176
+ }).toThrow("Aggregate functions cannot be nested");
124
177
  });
125
178
 
126
- test('Test with and return with unwind', async () => {
127
- const runner = new Runner('with [1, 2, 3] as a unwind a as b return b as renamed');
179
+ test("Test with and return with unwind", async () => {
180
+ const runner = new Runner("with [1, 2, 3] as a unwind a as b return b as renamed");
128
181
  await runner.run();
129
182
  const results = runner.results;
130
183
  expect(results.length).toBe(3);
131
- expect(results[0]).toEqual({'renamed': 1});
132
- expect(results[1]).toEqual({'renamed': 2});
133
- expect(results[2]).toEqual({'renamed': 3});
184
+ expect(results[0]).toEqual({ renamed: 1 });
185
+ expect(results[1]).toEqual({ renamed: 2 });
186
+ expect(results[2]).toEqual({ renamed: 3 });
134
187
  });
135
188
 
136
- test('Test predicate function', async () => {
137
- const runner = new Runner('RETURN sum(n in [1, 2, 3] | n where n > 1) as sum');
189
+ test("Test predicate function", async () => {
190
+ const runner = new Runner("RETURN sum(n in [1, 2, 3] | n where n > 1) as sum");
138
191
  await runner.run();
139
192
  const results = runner.results;
140
193
  expect(results.length).toBe(1);
141
- expect(results[0]).toEqual({'sum': 5});
194
+ expect(results[0]).toEqual({ sum: 5 });
142
195
  });
143
196
 
144
- test('Test predicate without where', async () => {
145
- const runner = new Runner('RETURN sum(n in [1, 2, 3] | n) as sum');
197
+ test("Test predicate without where", async () => {
198
+ const runner = new Runner("RETURN sum(n in [1, 2, 3] | n) as sum");
146
199
  await runner.run();
147
200
  const results = runner.results;
148
201
  expect(results.length).toBe(1);
149
- expect(results[0]).toEqual({'sum': 6});
202
+ expect(results[0]).toEqual({ sum: 6 });
150
203
  });
151
204
 
152
- test('Test predicate with return expression', async () => {
153
- const runner = new Runner('RETURN sum(n in [1+2+3, 2, 3] | n^2) as sum');
205
+ test("Test predicate with return expression", async () => {
206
+ const runner = new Runner("RETURN sum(n in [1+2+3, 2, 3] | n^2) as sum");
154
207
  await runner.run();
155
208
  const results = runner.results;
156
209
  expect(results.length).toBe(1);
157
- expect(results[0]).toEqual({'sum': 49});
210
+ expect(results[0]).toEqual({ sum: 49 });
158
211
  });
159
212
 
160
- test('Test range function', async () => {
161
- const runner = new Runner('RETURN range(1, 3) as range');
213
+ test("Test range function", async () => {
214
+ const runner = new Runner("RETURN range(1, 3) as range");
162
215
  await runner.run();
163
216
  const results = runner.results;
164
217
  expect(results.length).toBe(1);
165
- expect(results[0]).toEqual({'range': [1, 2, 3]});
218
+ expect(results[0]).toEqual({ range: [1, 2, 3] });
166
219
  });
167
220
 
168
- test('Test range function with unwind and case', async () => {
169
- const runner = new Runner('unwind range(1, 3) as num return case when num > 1 then num else null end as ret');
221
+ test("Test range function with unwind and case", async () => {
222
+ const runner = new Runner(
223
+ "unwind range(1, 3) as num return case when num > 1 then num else null end as ret"
224
+ );
170
225
  await runner.run();
171
226
  const results = runner.results;
172
227
  expect(results.length).toBe(3);
173
- expect(results[0]).toEqual({'ret': null});
174
- expect(results[1]).toEqual({'ret': 2});
175
- expect(results[2]).toEqual({'ret': 3});
228
+ expect(results[0]).toEqual({ ret: null });
229
+ expect(results[1]).toEqual({ ret: 2 });
230
+ expect(results[2]).toEqual({ ret: 3 });
176
231
  });
177
232
 
178
- test('Test size function', async () => {
179
- const runner = new Runner('RETURN size([1, 2, 3]) as size');
233
+ test("Test size function", async () => {
234
+ const runner = new Runner("RETURN size([1, 2, 3]) as size");
180
235
  await runner.run();
181
236
  const results = runner.results;
182
237
  expect(results.length).toBe(1);
183
- expect(results[0]).toEqual({'size': 3});
238
+ expect(results[0]).toEqual({ size: 3 });
184
239
  });
185
240
 
186
- test('Test rand and round functions', async () => {
187
- const runner = new Runner('RETURN round(rand() * 10) as rand');
241
+ test("Test rand and round functions", async () => {
242
+ const runner = new Runner("RETURN round(rand() * 10) as rand");
188
243
  await runner.run();
189
244
  const results = runner.results;
190
245
  expect(results.length).toBe(1);
191
246
  expect(results[0].rand).toBeLessThanOrEqual(10);
192
247
  });
193
248
 
194
- test('Test split function', async () => {
249
+ test("Test split function", async () => {
195
250
  const runner = new Runner('RETURN split("a,b,c", ",") as split');
196
251
  await runner.run();
197
252
  const results = runner.results;
198
253
  expect(results.length).toBe(1);
199
- expect(results[0]).toEqual({'split': ['a', 'b', 'c']});
254
+ expect(results[0]).toEqual({ split: ["a", "b", "c"] });
200
255
  });
201
256
 
202
- test('Test f-string', async () => {
203
- const runner = new Runner('with range(1,3) as numbers RETURN f"hello {sum(n in numbers | n)}" as f');
257
+ test("Test f-string", async () => {
258
+ const runner = new Runner(
259
+ 'with range(1,3) as numbers RETURN f"hello {sum(n in numbers | n)}" as f'
260
+ );
204
261
  await runner.run();
205
262
  const results = runner.results;
206
263
  expect(results.length).toBe(1);
207
- expect(results[0]).toEqual({'f': 'hello 6'});
264
+ expect(results[0]).toEqual({ f: "hello 6" });
208
265
  });
209
266
 
210
- test('Test aggregated with and return', async () => {
267
+ test("Test aggregated with and return", async () => {
211
268
  const runner = new Runner(
212
269
  `
213
270
  unwind [1, 1, 2, 2] as i
@@ -219,11 +276,11 @@ test('Test aggregated with and return', async () => {
219
276
  await runner.run();
220
277
  const results = runner.results;
221
278
  expect(results.length).toBe(2);
222
- expect(results[0]).toEqual({'i': 1, 'sum': 12});
223
- expect(results[1]).toEqual({'i': 2, 'sum': 12});
279
+ expect(results[0]).toEqual({ i: 1, sum: 12 });
280
+ expect(results[1]).toEqual({ i: 2, sum: 12 });
224
281
  });
225
282
 
226
- test('Test aggregated with using collect and return', async () => {
283
+ test("Test aggregated with using collect and return", async () => {
227
284
  const runner = new Runner(
228
285
  `
229
286
  unwind [1, 1, 2, 2] as i
@@ -235,11 +292,11 @@ test('Test aggregated with using collect and return', async () => {
235
292
  await runner.run();
236
293
  const results = runner.results;
237
294
  expect(results.length).toBe(2);
238
- expect(results[0]).toEqual({'i': 1, 'collected': [1, 2, 3, 1, 2, 3]});
239
- expect(results[1]).toEqual({'i': 2, 'collected': [1, 2, 3, 1, 2, 3]});
295
+ expect(results[0]).toEqual({ i: 1, collected: [1, 2, 3, 1, 2, 3] });
296
+ expect(results[1]).toEqual({ i: 2, collected: [1, 2, 3, 1, 2, 3] });
240
297
  });
241
298
 
242
- test('Test collect distinct', async () => {
299
+ test("Test collect distinct", async () => {
243
300
  const runner = new Runner(
244
301
  `
245
302
  unwind [1, 1, 2, 2] as i
@@ -251,11 +308,11 @@ test('Test collect distinct', async () => {
251
308
  await runner.run();
252
309
  const results = runner.results;
253
310
  expect(results.length).toBe(2);
254
- expect(results[0]).toEqual({'i': 1, 'collected': [1, 2, 3]});
255
- expect(results[1]).toEqual({'i': 2, 'collected': [1, 2, 3]});
311
+ expect(results[0]).toEqual({ i: 1, collected: [1, 2, 3] });
312
+ expect(results[1]).toEqual({ i: 2, collected: [1, 2, 3] });
256
313
  });
257
314
 
258
- test('Test collect distinct with associative array', async () => {
315
+ test("Test collect distinct with associative array", async () => {
259
316
  const runner = new Runner(
260
317
  `
261
318
  unwind [1, 1, 2, 2] as i
@@ -267,142 +324,153 @@ test('Test collect distinct with associative array', async () => {
267
324
  await runner.run();
268
325
  const results = runner.results;
269
326
  expect(results.length).toBe(2);
270
- expect(results[0]).toEqual({'i': 1, 'collected': [{'j': 1}, {'j': 2}, {'j': 3}]});
271
- expect(results[1]).toEqual({'i': 2, 'collected': [{'j': 1}, {'j': 2}, {'j': 3}]});
327
+ expect(results[0]).toEqual({ i: 1, collected: [{ j: 1 }, { j: 2 }, { j: 3 }] });
328
+ expect(results[1]).toEqual({ i: 2, collected: [{ j: 1 }, { j: 2 }, { j: 3 }] });
272
329
  });
273
330
 
274
- test('Test join function', async () => {
331
+ test("Test join function", async () => {
275
332
  const runner = new Runner('RETURN join(["a", "b", "c"], ",") as join');
276
333
  await runner.run();
277
334
  const results = runner.results;
278
335
  expect(results.length).toBe(1);
279
- expect(results[0]).toEqual({'join': 'a,b,c'});
336
+ expect(results[0]).toEqual({ join: "a,b,c" });
280
337
  });
281
338
 
282
- test('Test join function with empty array', async () => {
339
+ test("Test join function with empty array", async () => {
283
340
  const runner = new Runner('RETURN join([], ",") as join');
284
341
  await runner.run();
285
342
  const results = runner.results;
286
343
  expect(results.length).toBe(1);
287
- expect(results[0]).toEqual({'join': ''});
344
+ expect(results[0]).toEqual({ join: "" });
288
345
  });
289
346
 
290
- test('Test tojson function', async () => {
347
+ test("Test tojson function", async () => {
291
348
  const runner = new Runner('RETURN tojson(\'{"a": 1, "b": 2}\') as tojson');
292
349
  await runner.run();
293
350
  const results = runner.results;
294
351
  expect(results.length).toBe(1);
295
- expect(results[0]).toEqual({'tojson': {'a': 1, 'b': 2}});
352
+ expect(results[0]).toEqual({ tojson: { a: 1, b: 2 } });
296
353
  });
297
354
 
298
- test('Test tojson function with lookup', async () => {
355
+ test("Test tojson function with lookup", async () => {
299
356
  const runner = new Runner('RETURN tojson(\'{"a": 1, "b": 2}\').a as tojson');
300
357
  await runner.run();
301
358
  const results = runner.results;
302
359
  expect(results.length).toBe(1);
303
- expect(results[0]).toEqual({'tojson': 1});
360
+ expect(results[0]).toEqual({ tojson: 1 });
304
361
  });
305
362
 
306
- test('Test replace function', async () => {
363
+ test("Test replace function", async () => {
307
364
  const runner = new Runner('RETURN replace("hello", "l", "x") as replace');
308
365
  await runner.run();
309
366
  const results = runner.results;
310
367
  expect(results.length).toBe(1);
311
- expect(results[0]).toEqual({'replace': 'hexxo'});
368
+ expect(results[0]).toEqual({ replace: "hexxo" });
312
369
  });
313
370
 
314
- test('Test f-string with escaped braces', async () => {
315
- const runner = new Runner('with range(1,3) as numbers RETURN f"hello {{sum(n in numbers | n)}}" as f');
371
+ test("Test f-string with escaped braces", async () => {
372
+ const runner = new Runner(
373
+ 'with range(1,3) as numbers RETURN f"hello {{sum(n in numbers | n)}}" as f'
374
+ );
316
375
  await runner.run();
317
376
  const results = runner.results;
318
377
  expect(results.length).toBe(1);
319
- expect(results[0]).toEqual({'f': 'hello {sum(n in numbers | n)}'});
378
+ expect(results[0]).toEqual({ f: "hello {sum(n in numbers | n)}" });
320
379
  });
321
380
 
322
- test('Test predicate function with collection from lookup', async () => {
323
- const runner = new Runner('RETURN sum(n in tojson(\'{"a": [1, 2, 3]}\').a | n) as sum');
381
+ test("Test predicate function with collection from lookup", async () => {
382
+ const runner = new Runner("RETURN sum(n in tojson('{\"a\": [1, 2, 3]}').a | n) as sum");
324
383
  await runner.run();
325
384
  const results = runner.results;
326
385
  expect(results.length).toBe(1);
327
- expect(results[0]).toEqual({'sum': 6});
386
+ expect(results[0]).toEqual({ sum: 6 });
328
387
  });
329
388
 
330
- test('Test stringify function', async () => {
331
- const runner = new Runner('RETURN stringify({a: 1, b: 2}) as stringify');
389
+ test("Test stringify function", async () => {
390
+ const runner = new Runner("RETURN stringify({a: 1, b: 2}) as stringify");
332
391
  await runner.run();
333
392
  const results = runner.results;
334
393
  expect(results.length).toBe(1);
335
394
  expect(results[0]).toEqual({
336
- 'stringify': '{\n "a": 1,\n "b": 2\n}'
395
+ stringify: '{\n "a": 1,\n "b": 2\n}',
337
396
  });
338
397
  });
339
398
 
340
- test('Test associative array with key which is keyword', async () => {
341
- const runner = new Runner('RETURN {return: 1} as aa');
399
+ test("Test associative array with key which is keyword", async () => {
400
+ const runner = new Runner("RETURN {return: 1} as aa");
342
401
  await runner.run();
343
402
  const results = runner.results;
344
403
  expect(results.length).toBe(1);
345
- expect(results[0]).toEqual({'aa': {'return': 1}});
404
+ expect(results[0]).toEqual({ aa: { return: 1 } });
346
405
  });
347
406
 
348
- test('Test lookup which is keyword', async () => {
349
- const runner = new Runner('RETURN {return: 1}.return as aa');
407
+ test("Test lookup which is keyword", async () => {
408
+ const runner = new Runner("RETURN {return: 1}.return as aa");
350
409
  await runner.run();
351
410
  const results = runner.results;
352
411
  expect(results.length).toBe(1);
353
- expect(results[0]).toEqual({'aa': 1});
412
+ expect(results[0]).toEqual({ aa: 1 });
354
413
  });
355
414
 
356
- test('Test lookup which is keyword', async () => {
415
+ test("Test lookup which is keyword", async () => {
357
416
  const runner = new Runner('RETURN {return: 1}["return"] as aa');
358
417
  await runner.run();
359
418
  const results = runner.results;
360
419
  expect(results.length).toBe(1);
361
- expect(results[0]).toEqual({'aa': 1});
420
+ expect(results[0]).toEqual({ aa: 1 });
362
421
  });
363
422
 
364
- test('Test return with expression alias which starts with keyword', async () => {
423
+ test("Test return with expression alias which starts with keyword", async () => {
365
424
  const runner = new Runner('RETURN 1 as return1, ["hello", "world"] as notes');
366
425
  await runner.run();
367
426
  const results = runner.results;
368
427
  expect(results.length).toBe(1);
369
- expect(results[0]).toEqual({'return1': 1, 'notes': ['hello', 'world']});
428
+ expect(results[0]).toEqual({ return1: 1, notes: ["hello", "world"] });
370
429
  });
371
430
 
372
- test('Test load which should throw error', async () => {
431
+ test("Test load which should throw error", async () => {
373
432
  const runner = new Runner('load json from "http://non_existing" as data return data');
374
- runner.run().then().catch(e => {
375
- expect(e.message).toBe('Failed to load data from http://non_existing. Error: TypeError: fetch failed');
376
- });
433
+ runner
434
+ .run()
435
+ .then()
436
+ .catch((e) => {
437
+ expect(e.message).toBe(
438
+ "Failed to load data from http://non_existing. Error: TypeError: fetch failed"
439
+ );
440
+ });
377
441
  });
378
442
 
379
- test('Test return with where clause', async () => {
380
- const runner = new Runner('unwind range(1,100) as n with n return n where n >= 20 and n <= 30');
443
+ test("Test return with where clause", async () => {
444
+ const runner = new Runner("unwind range(1,100) as n with n return n where n >= 20 and n <= 30");
381
445
  await runner.run();
382
446
  const results = runner.results;
383
447
  expect(results.length).toBe(11);
384
- expect(results[0]).toEqual({'n': 20});
385
- expect(results[10]).toEqual({'n': 30});
448
+ expect(results[0]).toEqual({ n: 20 });
449
+ expect(results[10]).toEqual({ n: 30 });
386
450
  });
387
451
 
388
- test('Test return with where clause and expression alias', async () => {
389
- const runner = new Runner('unwind range(1,100) as n with n return n as number where n >= 20 and n <= 30');
452
+ test("Test return with where clause and expression alias", async () => {
453
+ const runner = new Runner(
454
+ "unwind range(1,100) as n with n return n as number where n >= 20 and n <= 30"
455
+ );
390
456
  await runner.run();
391
457
  const results = runner.results;
392
458
  expect(results.length).toBe(11);
393
- expect(results[0]).toEqual({'number': 20});
394
- expect(results[10]).toEqual({'number': 30});
459
+ expect(results[0]).toEqual({ number: 20 });
460
+ expect(results[10]).toEqual({ number: 30 });
395
461
  });
396
462
 
397
- test('Test aggregated return with where clause', async () => {
398
- const runner = new Runner('unwind range(1,100) as n with n where n >= 20 and n <= 30 return sum(n) as sum');
463
+ test("Test aggregated return with where clause", async () => {
464
+ const runner = new Runner(
465
+ "unwind range(1,100) as n with n where n >= 20 and n <= 30 return sum(n) as sum"
466
+ );
399
467
  await runner.run();
400
468
  const results = runner.results;
401
469
  expect(results.length).toBe(1);
402
- expect(results[0]).toEqual({'sum': 275});
470
+ expect(results[0]).toEqual({ sum: 275 });
403
471
  });
404
472
 
405
- test('Test chained aggregated return with where clause', async () => {
473
+ test("Test chained aggregated return with where clause", async () => {
406
474
  const runner = new Runner(
407
475
  `
408
476
  unwind [1, 1, 2, 2] as i
@@ -414,10 +482,10 @@ test('Test chained aggregated return with where clause', async () => {
414
482
  await runner.run();
415
483
  const results = runner.results;
416
484
  expect(results.length).toBe(1);
417
- expect(results[0]).toEqual({'i': 1, 'sum': 20});
485
+ expect(results[0]).toEqual({ i: 1, sum: 20 });
418
486
  });
419
487
 
420
- test('Test predicate function with collection from function', async () => {
488
+ test("Test predicate function with collection from function", async () => {
421
489
  const runner = new Runner(
422
490
  `
423
491
  unwind range(1, 10) as i
@@ -428,10 +496,10 @@ test('Test predicate function with collection from function', async () => {
428
496
  await runner.run();
429
497
  const results = runner.results;
430
498
  expect(results.length).toBe(10);
431
- expect(results[0]).toEqual({'i': 1, 'expr1': 55, 'expr2': 5.5, 'sum': 55});
499
+ expect(results[0]).toEqual({ i: 1, expr1: 55, expr2: 5.5, sum: 55 });
432
500
  });
433
501
 
434
- test('Test limit', async () => {
502
+ test("Test limit", async () => {
435
503
  const runner = new Runner(
436
504
  `
437
505
  unwind range(1, 10) as i
@@ -445,7 +513,7 @@ test('Test limit', async () => {
445
513
  expect(results.length).toBe(50);
446
514
  });
447
515
 
448
- test('Test range lookup', async () => {
516
+ test("Test range lookup", async () => {
449
517
  const runner = new Runner(
450
518
  `
451
519
  with range(1, 10) as numbers
@@ -459,21 +527,21 @@ test('Test range lookup', async () => {
459
527
  const results = runner.results;
460
528
  expect(results.length).toBe(1);
461
529
  expect(results[0]).toEqual({
462
- 'subset1': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
463
- 'subset2': [1, 2, 3],
464
- 'subset3': [1, 2, 3, 4, 5, 6, 7, 8]
530
+ subset1: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
531
+ subset2: [1, 2, 3],
532
+ subset3: [1, 2, 3, 4, 5, 6, 7, 8],
465
533
  });
466
534
  });
467
535
 
468
- test('Test return -1', async () => {
469
- const runner = new Runner('return -1 as num');
536
+ test("Test return -1", async () => {
537
+ const runner = new Runner("return -1 as num");
470
538
  await runner.run();
471
539
  const results = runner.results;
472
540
  expect(results.length).toBe(1);
473
- expect(results[0]).toEqual({'num': -1});
541
+ expect(results[0]).toEqual({ num: -1 });
474
542
  });
475
543
 
476
- test('Unwind range lookup', async () => {
544
+ test("Unwind range lookup", async () => {
477
545
  const runner = new Runner(`
478
546
  with range(1,10) as arr
479
547
  unwind arr[2:-2] as a
@@ -482,11 +550,11 @@ test('Unwind range lookup', async () => {
482
550
  await runner.run();
483
551
  const results = runner.results;
484
552
  expect(results.length).toBe(6);
485
- expect(results[0]).toEqual({'a': 3});
486
- expect(results[5]).toEqual({'a': 8});
553
+ expect(results[0]).toEqual({ a: 3 });
554
+ expect(results[5]).toEqual({ a: 8 });
487
555
  });
488
556
 
489
- test('Test range with size', async () => {
557
+ test("Test range with size", async () => {
490
558
  const runner = new Runner(`
491
559
  with range(1,10) as data
492
560
  return range(0, size(data)-1) as indices
@@ -494,18 +562,18 @@ test('Test range with size', async () => {
494
562
  await runner.run();
495
563
  const results = runner.results;
496
564
  expect(results.length).toBe(1);
497
- expect(results[0]).toEqual({'indices': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]});
565
+ expect(results[0]).toEqual({ indices: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] });
498
566
  });
499
567
 
500
- test('Test keys function', async () => {
568
+ test("Test keys function", async () => {
501
569
  const runner = new Runner('RETURN keys({name: "Alice", age: 30}) as keys');
502
570
  await runner.run();
503
571
  const results = runner.results;
504
572
  expect(results.length).toBe(1);
505
- expect(results[0]).toEqual({'keys': ['name', 'age']});
573
+ expect(results[0]).toEqual({ keys: ["name", "age"] });
506
574
  });
507
575
 
508
- test('Test type function', async () => {
576
+ test("Test type function", async () => {
509
577
  const runner = new Runner(`
510
578
  RETURN type(123) as type1,
511
579
  type("hello") as type2,
@@ -517,10 +585,54 @@ test('Test type function', async () => {
517
585
  const results = runner.results;
518
586
  expect(results.length).toBe(1);
519
587
  expect(results[0]).toEqual({
520
- 'type1': 'number',
521
- 'type2': 'string',
522
- 'type3': 'array',
523
- 'type4': 'object',
524
- 'type5': 'null'
588
+ type1: "number",
589
+ type2: "string",
590
+ type3: "array",
591
+ type4: "object",
592
+ type5: "null",
525
593
  });
526
- });
594
+ });
595
+
596
+ test("Test call operation with async function", async () => {
597
+ const runner = new Runner("CALL calltestfunction() YIELD result RETURN result");
598
+ await runner.run();
599
+ const results = runner.results;
600
+ expect(results.length).toBe(3);
601
+ expect(results[0]).toEqual({ result: 1 });
602
+ expect(results[1]).toEqual({ result: 2 });
603
+ expect(results[2]).toEqual({ result: 3 });
604
+ });
605
+
606
+ test("Test call operation with aggregation", async () => {
607
+ const runner = new Runner("CALL calltestfunction() YIELD result RETURN sum(result) as total");
608
+ await runner.run();
609
+ const results = runner.results;
610
+ expect(results.length).toBe(1);
611
+ expect(results[0]).toEqual({ total: 6 });
612
+ });
613
+
614
+ test("Test call operation as last operation", async () => {
615
+ const runner = new Runner("CALL calltestfunction()");
616
+ await runner.run();
617
+ const results = runner.results;
618
+ expect(results.length).toBe(3);
619
+ expect(results[0]).toEqual({ result: 1 });
620
+ expect(results[1]).toEqual({ result: 2 });
621
+ expect(results[2]).toEqual({ result: 3 });
622
+ });
623
+
624
+ test("Test call operation as last operation with yield", async () => {
625
+ const runner = new Runner("CALL calltestfunction() YIELD result");
626
+ await runner.run();
627
+ const results = runner.results;
628
+ expect(results.length).toBe(3);
629
+ expect(results[0]).toEqual({ result: 1 });
630
+ expect(results[1]).toEqual({ result: 2 });
631
+ expect(results[2]).toEqual({ result: 3 });
632
+ });
633
+
634
+ test("Test call operation with no yielded expressions", async () => {
635
+ expect(() => {
636
+ const runner = new Runner("CALL calltestfunctionnoobject() RETURN 1");
637
+ }).toThrow("CALL operations must have a YIELD clause unless they are the last operation");
638
+ });