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.
- package/.gitattributes +3 -0
- package/.github/workflows/python-publish.yml +56 -4
- package/.github/workflows/release.yml +25 -18
- package/README.md +37 -32
- package/dist/flowquery.min.js +1 -1
- package/dist/graph/data.d.ts.map +1 -1
- package/dist/graph/data.js +5 -3
- package/dist/graph/data.js.map +1 -1
- package/dist/graph/pattern.d.ts.map +1 -1
- package/dist/graph/pattern.js +11 -4
- package/dist/graph/pattern.js.map +1 -1
- package/dist/graph/relationship.d.ts.map +1 -1
- package/dist/graph/relationship.js +11 -4
- package/dist/graph/relationship.js.map +1 -1
- package/dist/index.d.ts +0 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -5
- package/dist/index.js.map +1 -1
- package/dist/parsing/parser.d.ts +5 -0
- package/dist/parsing/parser.d.ts.map +1 -1
- package/dist/parsing/parser.js +92 -72
- package/dist/parsing/parser.js.map +1 -1
- package/docs/flowquery.min.js +1 -1
- package/flowquery-py/misc/data/test.json +10 -0
- package/flowquery-py/misc/data/users.json +242 -0
- package/flowquery-py/notebooks/TestFlowQuery.ipynb +440 -0
- package/flowquery-py/pyproject.toml +4 -1
- package/flowquery-py/src/__init__.py +2 -0
- package/flowquery-py/src/graph/data.py +4 -3
- package/flowquery-py/src/graph/pattern.py +7 -4
- package/flowquery-py/src/graph/relationship.py +7 -0
- package/flowquery-py/src/parsing/parser.py +75 -58
- package/flowquery-py/tests/compute/test_runner.py +10 -7
- package/flowquery-vscode/flowQueryEngine/flowquery.min.js +1 -1
- package/package.json +1 -1
- package/src/graph/data.ts +5 -3
- package/src/graph/pattern.ts +13 -4
- package/src/graph/relationship.ts +8 -0
- package/src/index.ts +5 -6
- package/src/parsing/parser.ts +92 -71
- package/tests/compute/runner.test.ts +71 -79
package/.gitattributes
ADDED
|
@@ -2,13 +2,15 @@ name: Publish Python Package to PyPI
|
|
|
2
2
|
|
|
3
3
|
on:
|
|
4
4
|
push:
|
|
5
|
-
|
|
6
|
-
-
|
|
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 == '
|
|
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
|
-
-
|
|
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:
|
|
27
|
-
cache:
|
|
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
|
-
|
|
16
|
-
|
|
17
|
-
-
|
|
18
|
-
|
|
19
|
-
-
|
|
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(
|
|
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(
|
|
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
|
-
|
|
56
|
-
|
|
57
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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(
|
|
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,
|
|
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 {
|
|
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.
|
|
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
|
|