flowquery 1.0.18 → 1.0.20

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 (41) hide show
  1. package/.gitattributes +3 -0
  2. package/.github/workflows/python-publish.yml +56 -4
  3. package/.github/workflows/release.yml +25 -18
  4. package/README.md +37 -32
  5. package/dist/flowquery.min.js +1 -1
  6. package/dist/graph/data.d.ts.map +1 -1
  7. package/dist/graph/data.js +5 -3
  8. package/dist/graph/data.js.map +1 -1
  9. package/dist/graph/pattern.d.ts.map +1 -1
  10. package/dist/graph/pattern.js +11 -4
  11. package/dist/graph/pattern.js.map +1 -1
  12. package/dist/graph/relationship.d.ts.map +1 -1
  13. package/dist/graph/relationship.js +11 -4
  14. package/dist/graph/relationship.js.map +1 -1
  15. package/dist/index.d.ts +0 -7
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +5 -5
  18. package/dist/index.js.map +1 -1
  19. package/dist/parsing/parser.d.ts +5 -0
  20. package/dist/parsing/parser.d.ts.map +1 -1
  21. package/dist/parsing/parser.js +92 -72
  22. package/dist/parsing/parser.js.map +1 -1
  23. package/docs/flowquery.min.js +1 -1
  24. package/flowquery-py/misc/data/test.json +10 -0
  25. package/flowquery-py/misc/data/users.json +242 -0
  26. package/flowquery-py/notebooks/TestFlowQuery.ipynb +440 -0
  27. package/flowquery-py/pyproject.toml +4 -1
  28. package/flowquery-py/src/__init__.py +2 -0
  29. package/flowquery-py/src/graph/data.py +4 -3
  30. package/flowquery-py/src/graph/pattern.py +7 -4
  31. package/flowquery-py/src/graph/relationship.py +7 -0
  32. package/flowquery-py/src/parsing/parser.py +75 -58
  33. package/flowquery-py/tests/compute/test_runner.py +10 -7
  34. package/flowquery-vscode/flowQueryEngine/flowquery.min.js +1 -1
  35. package/package.json +1 -1
  36. package/src/graph/data.ts +5 -3
  37. package/src/graph/pattern.ts +13 -4
  38. package/src/graph/relationship.ts +8 -0
  39. package/src/index.ts +5 -6
  40. package/src/parsing/parser.ts +92 -71
  41. package/tests/compute/runner.test.ts +71 -79
package/.gitattributes ADDED
@@ -0,0 +1,3 @@
1
+ *.ipynb filter=nbstripout
2
+ *.zpln filter=nbstripout
3
+ *.ipynb diff=ipynb
@@ -2,13 +2,15 @@ name: Publish Python Package to PyPI
2
2
 
3
3
  on:
4
4
  push:
5
- tags:
6
- - "py-v*" # Trigger on tags like py-v1.0.1, py-v2.3.4, etc.
5
+ branches:
6
+ - main
7
+ paths:
8
+ - "flowquery-py/src/**"
7
9
  pull_request:
8
10
  branches:
9
11
  - main
10
12
  paths:
11
- - "flowquery-py/**"
13
+ - "flowquery-py/src/**"
12
14
  release:
13
15
  types: [published]
14
16
  workflow_dispatch:
@@ -22,9 +24,52 @@ on:
22
24
  - testpypi
23
25
  - pypi
24
26
 
27
+ permissions:
28
+ contents: write
29
+
25
30
  jobs:
31
+ bump-version:
32
+ name: Bump version
33
+ if: github.event_name == 'push' && github.ref == 'refs/heads/main' && !startsWith(github.ref, 'refs/tags/')
34
+ runs-on: ubuntu-latest
35
+ outputs:
36
+ new_version: ${{ steps.bump.outputs.new_version }}
37
+
38
+ steps:
39
+ - uses: actions/checkout@v4
40
+ with:
41
+ fetch-depth: 0
42
+ token: ${{ secrets.PAT_TOKEN }}
43
+
44
+ - name: Bump Python package version
45
+ id: bump
46
+ working-directory: flowquery-py
47
+ run: |
48
+ # Get current version from pyproject.toml
49
+ CURRENT=$(grep -Po '(?<=^version = ")[^"]+' pyproject.toml)
50
+ echo "Current version: $CURRENT"
51
+
52
+ # Parse and bump patch version
53
+ IFS='.' read -r major minor patch <<< "$CURRENT"
54
+ NEW_VERSION="$major.$minor.$((patch + 1))"
55
+ echo "New version: $NEW_VERSION"
56
+
57
+ # Update pyproject.toml
58
+ sed -i "s/^version = \"$CURRENT\"/version = \"$NEW_VERSION\"/" pyproject.toml
59
+
60
+ # Commit and push
61
+ git config user.name "github-actions[bot]"
62
+ git config user.email "github-actions[bot]@users.noreply.github.com"
63
+ git add pyproject.toml
64
+ git commit -m "chore(py): bump version to $NEW_VERSION [skip ci]"
65
+ git push
66
+
67
+ echo "new_version=$NEW_VERSION" >> $GITHUB_OUTPUT
68
+
26
69
  build:
27
70
  name: Build distribution
71
+ needs: [bump-version]
72
+ if: always() && (needs.bump-version.result == 'success' || needs.bump-version.result == 'skipped')
28
73
  runs-on: ubuntu-latest
29
74
  defaults:
30
75
  run:
@@ -32,6 +77,13 @@ jobs:
32
77
 
33
78
  steps:
34
79
  - uses: actions/checkout@v4
80
+ with:
81
+ ref: ${{ github.ref }}
82
+ fetch-depth: 0
83
+
84
+ - name: Pull latest changes
85
+ if: needs.bump-version.result == 'success'
86
+ run: git pull origin main
35
87
 
36
88
  - name: Set up Python
37
89
  uses: actions/setup-python@v5
@@ -75,7 +127,7 @@ jobs:
75
127
 
76
128
  publish-pypi:
77
129
  name: Publish to PyPI
78
- if: github.event_name == 'release' || startsWith(github.ref, 'refs/tags/py-v') || (github.event_name == 'workflow_dispatch' && github.event.inputs.target == 'pypi')
130
+ if: (github.event_name == 'push' && github.ref == 'refs/heads/main') || github.event_name == 'release' || (github.event_name == 'workflow_dispatch' && github.event.inputs.target == 'pypi')
79
131
  needs: build
80
132
  runs-on: ubuntu-latest
81
133
  environment:
@@ -5,7 +5,7 @@ on:
5
5
  branches:
6
6
  - main
7
7
  paths:
8
- - 'src/**'
8
+ - "src/**"
9
9
 
10
10
  permissions:
11
11
  contents: write
@@ -13,75 +13,82 @@ permissions:
13
13
  jobs:
14
14
  build-and-release:
15
15
  runs-on: ubuntu-latest
16
-
16
+
17
17
  steps:
18
18
  - name: Checkout code
19
19
  uses: actions/checkout@v4
20
20
  with:
21
21
  fetch-depth: 0
22
-
22
+
23
23
  - name: Setup Node.js
24
24
  uses: actions/setup-node@v4
25
25
  with:
26
- node-version: '20'
27
- cache: 'npm'
28
-
26
+ node-version: "20"
27
+ cache: "npm"
28
+
29
29
  - name: Install dependencies
30
30
  run: npm ci
31
-
31
+
32
32
  - name: Run tests
33
33
  run: npm test
34
-
34
+
35
35
  - name: Build project
36
36
  run: npm run build
37
-
37
+
38
38
  - name: Verify build artifacts
39
39
  run: |
40
40
  echo "Checking build artifacts..."
41
41
  ls -la dist/flowquery.min.js || echo "dist/flowquery.min.js not found"
42
-
42
+
43
43
  - name: Copy to VS Code extension
44
44
  run: |
45
45
  echo "Copying flowquery.min.js to VS Code extension..."
46
46
  mkdir -p flowquery-vscode/flowQueryEngine
47
47
  cp dist/flowquery.min.js flowquery-vscode/flowQueryEngine/
48
48
  ls -la flowquery-vscode/flowQueryEngine/
49
-
49
+
50
50
  - name: Copy to docs folder
51
51
  run: |
52
52
  echo "Copying flowquery.min.js to docs folder for GitHub Pages..."
53
53
  cp dist/flowquery.min.js docs/
54
54
  ls -la docs/flowquery.min.js
55
-
55
+
56
56
  - name: Bump version
57
57
  id: version
58
58
  run: |
59
59
  git config user.name "github-actions[bot]"
60
60
  git config user.email "github-actions[bot]@users.noreply.github.com"
61
-
61
+
62
62
  # Bump patch version (use 'minor' or 'major' for other bump types)
63
63
  npm version patch --no-git-tag-version
64
-
64
+
65
65
  NEW_VERSION=$(node -p "require('./package.json').version")
66
66
  echo "version=${NEW_VERSION}" >> $GITHUB_OUTPUT
67
67
  echo "tag=v${NEW_VERSION}" >> $GITHUB_OUTPUT
68
-
68
+
69
69
  # Commit the version bump
70
70
  git add package.json package-lock.json docs/flowquery.min.js
71
71
  git commit -m "chore: bump version to ${NEW_VERSION} [skip ci]"
72
+
73
+ # Include any changes from formatters/linters in the commit
74
+ git add -A
75
+ git diff --cached --quiet || git commit --amend --no-edit
76
+
77
+ # Pull latest changes and rebase our commit on top
78
+ git pull --rebase origin main
72
79
  git push
73
-
80
+
74
81
  - name: Install VS Code extension dependencies
75
82
  working-directory: ./flowquery-vscode
76
83
  run: |
77
84
  npm install @vscode/vsce
78
-
85
+
79
86
  - name: Package VS Code extension
80
87
  working-directory: ./flowquery-vscode
81
88
  run: |
82
89
  npx @vscode/vsce package
83
90
  ls -la *.vsix
84
-
91
+
85
92
  - name: Create GitHub Release
86
93
  uses: softprops/action-gh-release@v1
87
94
  with:
package/README.md CHANGED
@@ -12,11 +12,12 @@ FlowQuery is written in TypeScript (https://www.typescriptlang.org/) and built/c
12
12
  - Try as a VSCode plugin from https://marketplace.visualstudio.com/items?itemName=FlowQuery.flowquery-vscode.
13
13
 
14
14
  ## Howto
15
- - Dev: ```npm start```
16
- - This will start a FlowQuery command line where you can run statements.
17
- - Test: ```npm test```
18
- - This will run all unit tests.
19
- - Build: ```npm run build``` (builds for both Node and web)
15
+
16
+ - Dev: `npm start`
17
+ - This will start a FlowQuery command line where you can run statements.
18
+ - Test: `npm test`
19
+ - This will run all unit tests.
20
+ - Build: `npm run build` (builds for both Node and web)
20
21
 
21
22
  ## Installation & Usage
22
23
 
@@ -31,12 +32,12 @@ npm install flowquery
31
32
  Then use it in your code:
32
33
 
33
34
  ```javascript
34
- const FlowQuery = require('flowquery').default;
35
+ const FlowQuery = require("flowquery").default;
35
36
  // Or with ES modules:
36
37
  // import FlowQuery from 'flowquery';
37
38
 
38
39
  async function main() {
39
- const query = new FlowQuery('WITH 1 AS x RETURN x + 1');
40
+ const query = new FlowQuery("WITH 1 AS x RETURN x + 1");
40
41
  await query.run();
41
42
  console.log(query.results); // [ { expr0: 2 } ]
42
43
  }
@@ -51,20 +52,20 @@ Include the minified bundle in your HTML:
51
52
  ```html
52
53
  <script src="https://microsoft.github.io/FlowQuery/flowquery.min.js"></script>
53
54
  <script>
54
- async function main() {
55
- const query = new FlowQuery('WITH 1 AS x RETURN x + 1');
56
- await query.run();
57
- console.log(query.results); // [ { expr0: 2 } ]
58
- }
55
+ async function main() {
56
+ const query = new FlowQuery("WITH 1 AS x RETURN x + 1");
57
+ await query.run();
58
+ console.log(query.results); // [ { expr0: 2 } ]
59
+ }
59
60
 
60
- main();
61
+ main();
61
62
  </script>
62
63
  ```
63
64
 
64
65
  Or import from the browser-specific entry point:
65
66
 
66
67
  ```javascript
67
- import FlowQuery from 'flowquery/browser';
68
+ import FlowQuery from "flowquery/browser";
68
69
 
69
70
  const query = new FlowQuery('WITH "Hello" AS greeting RETURN greeting');
70
71
  await query.run();
@@ -72,7 +73,9 @@ console.log(query.results);
72
73
  ```
73
74
 
74
75
  ## Examples
76
+
75
77
  See also ./misc/queries and ./tests/compute/runner.test.ts for more examples.
78
+
76
79
  ```cypher
77
80
  /*
78
81
  Collect 10 random pieces of wisdom and create a letter histogram.
@@ -83,12 +86,13 @@ with join(collect(item.slip.advice),"") as wisdom
83
86
  unwind split(wisdom,"") as letter
84
87
  return letter, sum(1) as lettercount
85
88
  ```
89
+
86
90
  ```cypher
87
91
  /*
88
92
  This query fetches 10 cat facts from the Cat Facts API (https://catfact.ninja/fact)
89
93
  and then uses the OpenAI API to analyze those cat facts and return a short summary
90
94
  of the most interesting facts and what they imply about cats as pets.
91
-
95
+
92
96
  To run this query, you need to set the OPENAI_API_KEY variable to your OpenAI API key.
93
97
  You also need to set the OpenAI-Organization header to your organization ID.
94
98
  You can find your organization ID in the OpenAI dashboard.
@@ -127,6 +131,7 @@ with openai_response.choices[0].message.content as catfacts_analysis
127
131
  // Return the analysis
128
132
  return catfacts_analysis
129
133
  ```
134
+
130
135
  ```cypher
131
136
  // Test completion from Azure OpenAI API
132
137
  with
@@ -153,12 +158,12 @@ Import the necessary classes and decorators from the extensibility module:
153
158
 
154
159
  ```typescript
155
160
  import {
156
- Function,
157
161
  AggregateFunction,
162
+ Function,
163
+ FunctionDef,
158
164
  PredicateFunction,
159
165
  ReducerElement,
160
- FunctionDef
161
- } from 'flowquery/extensibility';
166
+ } from "flowquery/extensibility";
162
167
  ```
163
168
 
164
169
  ### Creating a Custom Scalar Function
@@ -166,20 +171,20 @@ import {
166
171
  Scalar functions operate on individual values and return a result:
167
172
 
168
173
  ```typescript
169
- import { Function, FunctionDef } from 'flowquery/extensibility';
174
+ import { Function, FunctionDef } from "flowquery/extensibility";
170
175
 
171
176
  @FunctionDef({
172
177
  description: "Doubles a number",
173
178
  category: "scalar",
174
179
  parameters: [{ name: "value", description: "Number to double", type: "number" }],
175
- output: { description: "Doubled value", type: "number" }
180
+ output: { description: "Doubled value", type: "number" },
176
181
  })
177
182
  class Double extends Function {
178
183
  constructor() {
179
184
  super("double");
180
185
  this._expectedParameterCount = 1;
181
186
  }
182
-
187
+
183
188
  public value(): number {
184
189
  return this.getChildren()[0].value() * 2;
185
190
  }
@@ -196,23 +201,23 @@ WITH 5 AS num RETURN double(num) AS result
196
201
  ### Creating a Custom String Function
197
202
 
198
203
  ```typescript
199
- import { Function, FunctionDef } from 'flowquery/extensibility';
204
+ import { Function, FunctionDef } from "flowquery/extensibility";
200
205
 
201
206
  @FunctionDef({
202
207
  description: "Reverses a string",
203
208
  category: "scalar",
204
209
  parameters: [{ name: "text", description: "String to reverse", type: "string" }],
205
- output: { description: "Reversed string", type: "string" }
210
+ output: { description: "Reversed string", type: "string" },
206
211
  })
207
212
  class StrReverse extends Function {
208
213
  constructor() {
209
214
  super("strreverse");
210
215
  this._expectedParameterCount = 1;
211
216
  }
212
-
217
+
213
218
  public value(): string {
214
219
  const input = String(this.getChildren()[0].value());
215
- return input.split('').reverse().join('');
220
+ return input.split("").reverse().join("");
216
221
  }
217
222
  }
218
223
  ```
@@ -229,7 +234,7 @@ WITH 'hello' AS s RETURN strreverse(s) AS reversed
229
234
  Aggregate functions process multiple values and return a single result. They require a `ReducerElement` to track state:
230
235
 
231
236
  ```typescript
232
- import { AggregateFunction, ReducerElement, FunctionDef } from 'flowquery/extensibility';
237
+ import { AggregateFunction, FunctionDef, ReducerElement } from "flowquery/extensibility";
233
238
 
234
239
  class ProductElement extends ReducerElement {
235
240
  private _value: number = 1;
@@ -245,18 +250,18 @@ class ProductElement extends ReducerElement {
245
250
  description: "Calculates the product of values",
246
251
  category: "aggregate",
247
252
  parameters: [{ name: "value", description: "Number to multiply", type: "number" }],
248
- output: { description: "Product of all values", type: "number" }
253
+ output: { description: "Product of all values", type: "number" },
249
254
  })
250
255
  class Product extends AggregateFunction {
251
256
  constructor() {
252
257
  super("product");
253
258
  this._expectedParameterCount = 1;
254
259
  }
255
-
260
+
256
261
  public reduce(element: ReducerElement): void {
257
262
  element.value = this.firstChild().value();
258
263
  }
259
-
264
+
260
265
  public element(): ReducerElement {
261
266
  return new ProductElement();
262
267
  }
@@ -275,13 +280,13 @@ UNWIND [2, 3, 4] AS num RETURN product(num) AS result
275
280
  Async providers allow you to create custom data sources that can be used with `LOAD JSON FROM`:
276
281
 
277
282
  ```typescript
278
- import { FunctionDef, AsyncFunction } from 'flowquery/extensibility';
283
+ import { AsyncFunction, FunctionDef } from "flowquery/extensibility";
279
284
 
280
285
  @FunctionDef({
281
286
  description: "Provides example data for testing",
282
287
  category: "async",
283
288
  parameters: [],
284
- output: { description: "Example data object", type: "object" }
289
+ output: { description: "Example data object", type: "object" },
285
290
  })
286
291
  class GetExampleData extends AsyncFunction {
287
292
  async *generate(): AsyncGenerator<any> {
@@ -323,7 +328,7 @@ RETURN f.name AS name, f.description AS description, f.category AS category
323
328
 
324
329
  ## Contributing
325
330
 
326
- This project welcomes contributions and suggestions. Most contributions require you to agree to a
331
+ This project welcomes contributions and suggestions. Most contributions require you to agree to a
327
332
  Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us
328
333
  the rights to use your contribution. For details, visit [Contributor License Agreements](https://cla.opensource.microsoft.com).
329
334