├── .changeset ├── README.md └── config.json ├── .github └── workflows │ ├── cla-assistant.yml │ ├── cla-check.yml │ ├── docs.yml │ ├── lint.yml │ ├── release.yml │ ├── sonarcloud.yml │ └── test.yml ├── .gitignore ├── .prettierignore ├── .prettierrc ├── CHANGELOG.md ├── DEVELOPING.md ├── LICENSE.txt ├── README.md ├── addlicense ├── docs ├── .gitignore ├── README.adoc ├── antora.yml ├── modules │ └── ROOT │ │ ├── content-nav.adoc │ │ └── pages │ │ ├── clauses │ │ ├── create.adoc │ │ ├── foreach.adoc │ │ ├── load-csv.adoc │ │ ├── match.adoc │ │ ├── merge.adoc │ │ ├── return.adoc │ │ ├── set.adoc │ │ ├── union.adoc │ │ ├── unwind.adoc │ │ ├── use.adoc │ │ └── with.adoc │ │ ├── compatibility.adoc │ │ ├── functions.adoc │ │ ├── getting-started │ │ ├── connecting-to-neo4j.adoc │ │ ├── filters-and-projections.adoc │ │ ├── installation.adoc │ │ ├── querying.adoc │ │ └── relationships-and-advanced-filtering.adoc │ │ ├── how-to │ │ ├── concatenate-clauses.adoc │ │ ├── conditional-expressions.adoc │ │ ├── customize-cypher.adoc │ │ ├── define-cypher-version.adoc │ │ ├── filter-by-labels.adoc │ │ ├── type-predicate-expressions.adoc │ │ ├── update-labels.adoc │ │ └── use-change-data-capture.adoc │ │ ├── index.adoc │ │ ├── migration-guide-2.adoc │ │ ├── patterns.adoc │ │ ├── procedures.adoc │ │ ├── subqueries │ │ ├── call.adoc │ │ ├── collect.adoc │ │ ├── count.adoc │ │ └── exists.adoc │ │ └── variables-and-params │ │ ├── aliasing.adoc │ │ ├── lists.adoc │ │ ├── literals.adoc │ │ ├── maps.adoc │ │ ├── parameters.adoc │ │ └── variables.adoc ├── package.json ├── preview.yml ├── publish.yml └── server.js ├── eslint.config.mjs ├── examples ├── README.md ├── clauses │ ├── create.ts │ ├── foreach.ts │ ├── match.ts │ ├── merge.ts │ ├── union.ts │ ├── unwind.ts │ ├── use.ts │ └── with.ts ├── expressions │ ├── generic-case.ts │ └── simple-case.ts ├── functions │ └── trim.ts ├── patterns │ ├── label-expressions.ts │ ├── length.ts │ └── quantified-path-patterns.ts ├── procedures │ ├── custom-procedures.ts │ └── procedures.ts ├── raw-cypher │ ├── raw-cypher-complex.ts │ └── raw-cypher-simple.ts └── where │ ├── complex-where-match.ts │ ├── has-label.ts │ └── has-type.ts ├── global.d.ts ├── jest.config.js ├── package.json ├── renovate.json ├── sonar-project.properties ├── src ├── Cypher.ts ├── CypherASTNode.ts ├── Environment.test.ts ├── Environment.ts ├── clauses │ ├── Call.test.ts │ ├── Call.ts │ ├── Clause.ts │ ├── Create.test.ts │ ├── Create.ts │ ├── Finish.test.ts │ ├── Finish.ts │ ├── Foreach.test.ts │ ├── Foreach.ts │ ├── LoadCSV.test.ts │ ├── LoadCSV.ts │ ├── Match.test.ts │ ├── Match.ts │ ├── Merge.test.ts │ ├── Merge.ts │ ├── Raw.test.ts │ ├── Raw.ts │ ├── Return.test.ts │ ├── Return.ts │ ├── Union.test.ts │ ├── Union.ts │ ├── Unwind.test.ts │ ├── Unwind.ts │ ├── Use.test.ts │ ├── Use.ts │ ├── With.test.ts │ ├── With.ts │ ├── mixins │ │ ├── Mixin.ts │ │ ├── clauses │ │ │ ├── WithCall.ts │ │ │ ├── WithCallProcedure.ts │ │ │ ├── WithCreate.ts │ │ │ ├── WithFinish.ts │ │ │ ├── WithForeach.ts │ │ │ ├── WithMatch.ts │ │ │ ├── WithMerge.ts │ │ │ ├── WithReturn.ts │ │ │ ├── WithUnwind.ts │ │ │ └── WithWith.ts │ │ └── sub-clauses │ │ │ ├── WithDelete.ts │ │ │ ├── WithOrder.ts │ │ │ ├── WithSetRemove.ts │ │ │ └── WithWhere.ts │ ├── sub-clauses │ │ ├── Delete.ts │ │ ├── ImportWith.ts │ │ ├── OnCreate.ts │ │ ├── OnMatch.ts │ │ ├── OrderBy.test.ts │ │ ├── OrderBy.ts │ │ ├── Projection.ts │ │ ├── Remove.test.ts │ │ ├── Remove.ts │ │ ├── Set.test.ts │ │ ├── Set.ts │ │ └── Where.ts │ └── utils │ │ ├── concat.ts │ │ └── mixin.ts ├── expressions │ ├── Case.test.ts │ ├── Case.ts │ ├── HasLabel.test.ts │ ├── HasLabel.ts │ ├── IsType.test.ts │ ├── IsType.ts │ ├── functions │ │ ├── CypherFunctions.test.ts │ │ ├── CypherFunctions.ts │ │ ├── aggregation.test.ts │ │ ├── aggregation.ts │ │ ├── graph.test.ts │ │ ├── graph.ts │ │ ├── list.test.ts │ │ ├── list.ts │ │ ├── load-csv.test.ts │ │ ├── load-csv.ts │ │ ├── math.test.ts │ │ ├── math.ts │ │ ├── path.test.ts │ │ ├── path.ts │ │ ├── predicate.test.ts │ │ ├── predicate.ts │ │ ├── scalar.test.ts │ │ ├── scalar.ts │ │ ├── spatial.test.ts │ │ ├── spatial.ts │ │ ├── string.test.ts │ │ ├── string.ts │ │ ├── temporal.test.ts │ │ └── temporal.ts │ ├── labels │ │ ├── label-expressions.test.ts │ │ └── label-expressions.ts │ ├── list │ │ ├── ListComprehension.test.ts │ │ ├── ListComprehension.ts │ │ ├── ListExpr.test.ts │ │ ├── ListExpr.ts │ │ ├── ListIndex.test.ts │ │ ├── ListIndex.ts │ │ ├── PatternComprehension.test.ts │ │ └── PatternComprehension.ts │ ├── map │ │ ├── MapExpr.test.ts │ │ ├── MapExpr.ts │ │ ├── MapProjection.test.ts │ │ └── MapProjection.ts │ ├── operations │ │ ├── boolean.test.ts │ │ ├── boolean.ts │ │ ├── comparison.test.ts │ │ ├── comparison.ts │ │ ├── concat.test.ts │ │ ├── concat.ts │ │ ├── math.test.ts │ │ └── math.ts │ └── subquery │ │ ├── Collect.test.ts │ │ ├── Collect.ts │ │ ├── Count.test.ts │ │ ├── Count.ts │ │ ├── Exists.test.ts │ │ ├── Exists.ts │ │ └── Subquery.ts ├── index.ts ├── namespaces │ ├── apoc │ │ ├── apoc.ts │ │ ├── cypher │ │ │ ├── cypher.ts │ │ │ ├── run-first-column.test.ts │ │ │ └── run-first-column.ts │ │ ├── date.test.ts │ │ ├── date.ts │ │ ├── util.test.ts │ │ └── util.ts │ ├── db │ │ ├── cdc.test.ts │ │ ├── cdc.ts │ │ ├── db.test.ts │ │ ├── db.ts │ │ ├── index │ │ │ ├── dbIndex.ts │ │ │ ├── fulltext.test.ts │ │ │ ├── fulltext.ts │ │ │ ├── vector.test.ts │ │ │ └── vector.ts │ │ ├── schema.test.ts │ │ └── schema.ts │ ├── genai │ │ ├── genai.test.ts │ │ ├── genai.ts │ │ └── vector.ts │ ├── tx.test.ts │ ├── tx.ts │ └── vector │ │ ├── similarity.ts │ │ ├── vector.test.ts │ │ └── vector.ts ├── pattern │ ├── PartialPattern.ts │ ├── PathAssign.ts │ ├── Pattern.test.ts │ ├── Pattern.ts │ ├── PatternElement.ts │ ├── labels-to-string.ts │ └── quantified-patterns │ │ ├── QuantifiedPath.test.ts │ │ ├── QuantifiedPath.ts │ │ ├── QuantifiedPattern.test.ts │ │ └── QuantifiedPattern.ts ├── procedures │ ├── CypherProcedure.test.ts │ ├── CypherProcedure.ts │ └── Yield.ts ├── references │ ├── Label.ts │ ├── Literal.test.ts │ ├── Literal.ts │ ├── NodeRef.ts │ ├── Param.test.ts │ ├── Param.ts │ ├── Path.ts │ ├── PropertyRef.test.ts │ ├── PropertyRef.ts │ ├── RelationshipRef.test.ts │ ├── RelationshipRef.ts │ ├── Variable.test.ts │ └── Variable.ts ├── types.ts └── utils │ ├── TestClause.ts │ ├── add-label-token.test.ts │ ├── add-label-token.ts │ ├── as-array.test.ts │ ├── as-array.ts │ ├── compile-cypher-if-exists.ts │ ├── concat.test.ts │ ├── concat.ts │ ├── escape.test.ts │ ├── escape.ts │ ├── filter-truthy.ts │ ├── is-cypher-compilable.ts │ ├── is-number.ts │ ├── is-string.ts │ ├── normalize-variable.test.ts │ ├── normalize-variable.ts │ ├── pad-block.ts │ ├── pad-left.test.ts │ ├── pad-left.ts │ ├── serialize-map.test.ts │ ├── serialize-map.ts │ ├── stringify-object.test.ts │ ├── stringify-object.ts │ ├── to-cypher-params.ts │ ├── type-helpers.ts │ ├── utils.test.ts │ └── utils.ts ├── tests ├── build-config │ ├── cypher-version.test.ts │ ├── extra-params.test.ts │ ├── label-operator.test.ts │ └── unsafe-escape.test.ts ├── clause-chaining.test.ts ├── console-log.test.ts ├── deprecated │ ├── Foreach.test.ts │ └── concat.test.ts ├── examples.test.ts ├── issues │ ├── 462.test.ts │ └── 514.test.ts └── variable-escaping.test.ts ├── tsconfig.json ├── tsconfig.production.json ├── tsdoc.json └── typedoc.json /.changeset/README.md: -------------------------------------------------------------------------------- 1 | # Changesets 2 | 3 | Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works 4 | with multi-package repos, or single-package repos to help you version and publish your code. You can 5 | find the full documentation for it [in our repository](https://github.com/changesets/changesets) 6 | 7 | We have a quick list of common questions to get you started engaging with this project in 8 | [our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md) 9 | -------------------------------------------------------------------------------- /.changeset/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://unpkg.com/@changesets/config@2.3.0/schema.json", 3 | "changelog": ["@changesets/changelog-github", { "repo": "neo4j/cypher-builder" }], 4 | "commit": false, 5 | "fixed": [], 6 | "linked": [], 7 | "access": "public", 8 | "baseBranch": "main", 9 | "updateInternalDependencies": "patch", 10 | "ignore": [] 11 | } 12 | -------------------------------------------------------------------------------- /.github/workflows/cla-check.yml: -------------------------------------------------------------------------------- 1 | name: "CLA Check" 2 | 3 | on: 4 | pull_request_target: 5 | branches: ["main"] 6 | 7 | jobs: 8 | cla-check: 9 | if: github.event.pull_request.user.login != 'renovate[bot]' 10 | 11 | runs-on: ubuntu-latest 12 | 13 | steps: 14 | - uses: actions/checkout@v4 15 | with: 16 | repository: neo-technology/whitelist-check 17 | token: ${{ secrets.NEO4J_TEAM_GRAPHQL_PERSONAL_ACCESS_TOKEN }} 18 | - uses: actions/setup-python@v5 19 | with: 20 | python-version: 3 21 | - name: Install dependencies 22 | run: | 23 | python -m pip install --upgrade pip 24 | if [ -f requirements.txt ]; then pip install -r requirements.txt; fi 25 | - run: | 26 | owner=$(echo "$GITHUB_REPOSITORY" | cut -d/ -f1) 27 | repository=$(echo "$GITHUB_REPOSITORY" | cut -d/ -f2) 28 | 29 | ./bin/examine-pull-request "$owner" "$repository" "${{ secrets.NEO4J_TEAM_GRAPHQL_PERSONAL_ACCESS_TOKEN }}" "$PULL_REQUEST_NUMBER" cla-database.csv 30 | env: 31 | PULL_REQUEST_NUMBER: ${{ github.event.number }} 32 | -------------------------------------------------------------------------------- /.github/workflows/docs.yml: -------------------------------------------------------------------------------- 1 | # Simple workflow for deploying static content to GitHub Pages 2 | name: Deploy Docs 3 | 4 | on: 5 | # Allows you to run this workflow manually from the Actions tab 6 | workflow_dispatch: 7 | workflow_call: 8 | 9 | # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages 10 | permissions: 11 | contents: read 12 | pages: write 13 | id-token: write 14 | 15 | # Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. 16 | # However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. 17 | concurrency: 18 | group: "pages" 19 | cancel-in-progress: false 20 | 21 | jobs: 22 | # Single deploy job since we're just deploying 23 | deploy: 24 | environment: 25 | name: github-pages 26 | url: ${{ steps.deployment.outputs.page_url }} 27 | runs-on: ubuntu-latest 28 | steps: 29 | - name: Checkout 30 | uses: actions/checkout@v4 31 | - name: Setup Node.js 32 | uses: actions/setup-node@v4 33 | with: 34 | node-version: lts/* 35 | - name: Install Dependencies 36 | run: | 37 | npm install 38 | cd docs && npm install 39 | - name: Setup Pages 40 | uses: actions/configure-pages@v5 41 | - name: Build Docs 42 | run: | 43 | npm run docs 44 | touch ./docs/build/site/.nojekyll 45 | - name: Upload artifact 46 | uses: actions/upload-pages-artifact@v3 47 | with: 48 | # Upload docs 49 | path: "./docs/build/site" 50 | - name: Deploy to GitHub Pages 51 | id: deployment 52 | uses: actions/deploy-pages@v4 53 | -------------------------------------------------------------------------------- /.github/workflows/lint.yml: -------------------------------------------------------------------------------- 1 | name: Lint 2 | 3 | on: 4 | push: 5 | branches: ["main"] 6 | pull_request: 7 | branches: ["main"] 8 | 9 | jobs: 10 | lint: 11 | runs-on: ubuntu-latest 12 | 13 | steps: 14 | - uses: actions/checkout@v4 15 | - name: Use Node.js 16 | uses: actions/setup-node@v4 17 | with: 18 | node-version: lts/* 19 | - run: npm install 20 | - run: npm run lint 21 | 22 | license-header-check: 23 | runs-on: ubuntu-latest 24 | 25 | steps: 26 | - uses: actions/checkout@v4 27 | - uses: actions/setup-go@v5 28 | with: 29 | go-version: "^1.17.0" 30 | - name: Install addlicense 31 | run: go install github.com/google/addlicense@latest 32 | - name: Run addlicense 33 | run: addlicense -f ./addlicense -check $(find . -name "*.ts" -type f -print0 | xargs -0) 34 | 35 | prettier: 36 | runs-on: ubuntu-latest 37 | 38 | steps: 39 | - uses: actions/checkout@v4 40 | - name: Use Node.js lts/* 41 | uses: actions/setup-node@v4 42 | with: 43 | node-version: lts/* 44 | - run: npm install 45 | - name: "Run Prettier" 46 | run: npm run prettier 47 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Test 2 | 3 | on: 4 | push: 5 | branches: ["main"] 6 | pull_request: 7 | branches: ["main"] 8 | 9 | jobs: 10 | test: 11 | runs-on: ubuntu-latest 12 | 13 | strategy: 14 | matrix: 15 | node-version: [16.x, latest] 16 | 17 | steps: 18 | - uses: actions/checkout@v4 19 | - name: Use Node.js ${{ matrix.node-version }} 20 | uses: actions/setup-node@v4 21 | with: 22 | node-version: ${{ matrix.node-version }} 23 | - run: npm install 24 | - run: npm run build --if-present 25 | - run: npm test 26 | 27 | test-lts-with-coverage: 28 | runs-on: ubuntu-latest 29 | 30 | steps: 31 | - uses: actions/checkout@v4 32 | - name: Use Node.js LTS 33 | uses: actions/setup-node@v4 34 | with: 35 | node-version: lts/* 36 | - run: npm install 37 | - run: npm run build --if-present 38 | - run: npm test -- --coverage 39 | - name: Upload code coverage 40 | uses: actions/upload-artifact@v4 41 | with: 42 | name: coverage 43 | path: coverage/lcov.info 44 | 45 | examples: 46 | runs-on: ubuntu-latest 47 | 48 | steps: 49 | - name: Checkout repository 50 | uses: actions/checkout@v4 51 | 52 | - name: Set up Node.js 53 | uses: actions/setup-node@v4 54 | with: 55 | node-version: lts/* 56 | 57 | - name: Install dependencies 58 | run: | 59 | npm install 60 | npm install -g tsx 61 | - run: npm run build 62 | - name: Run Examples 63 | run: | 64 | examples=$(find ./examples -name "*.ts") 65 | for example in $examples; do 66 | echo "Run example $example" 67 | tsx $example > /dev/null 68 | exit_code=$? 69 | if [ $exit_code -ne 0 ]; then 70 | echo "Error executing $example" 71 | exit 1 72 | fi 73 | done 74 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | lerna-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (https://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # Build directories 40 | dist/ 41 | tmp/ 42 | 43 | # Optional npm cache directory 44 | .npm 45 | 46 | # Optional eslint cache 47 | .eslintcache 48 | 49 | # Optional REPL history 50 | .node_repl_history 51 | 52 | # Output of 'npm pack' 53 | *.tgz 54 | 55 | # Yarn Integrity file 56 | .yarn-integrity 57 | 58 | # dotenv environment variables file 59 | .env 60 | 61 | # next.js build output 62 | .next 63 | 64 | # IDEA 65 | .idea 66 | 67 | # VS Code 68 | .vscode/* 69 | 70 | 71 | # OSX 72 | .DS_Store 73 | 74 | # Oclif generated file 75 | oclif.manifest.json 76 | 77 | package-lock.json 78 | yarn.lock 79 | 80 | .yarn/ 81 | .pnp.* 82 | 83 | tsconfig.tsbuildinfo 84 | tsconfig.*.tsbuildinfo 85 | tsconfig.*.tsbuildinfo.gz 86 | 87 | .history 88 | 89 | docs/reference/ 90 | docs/build/ 91 | 92 | reports/ 93 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | CHANGELOG.md 2 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "endOfLine": "auto", 3 | "tabWidth": 4, 4 | "printWidth": 120, 5 | "trailingComma": "es5", 6 | "bracketSameLine": true, 7 | "semi": true, 8 | "overrides": [ 9 | { 10 | "files": ["*.yaml", "*.yml"], 11 | "options": { 12 | "tabWidth": 2 13 | } 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /DEVELOPING.md: -------------------------------------------------------------------------------- 1 | # Development 2 | 3 | - `npm test` to run cypher builder tests. Most tests are located next to the code that are testing as a `.test.ts` file 4 | - `npm run build` to compile cypher builder library 5 | - `npm run docs` to generate the API reference docs 6 | 7 | ## Link Cypher Builder locally with yarn 8 | 9 | In the Cypher Builder folder run: 10 | 11 | - `yarn link` 12 | - `yarn build` 13 | 14 | In the root of the package run: 15 | 16 | - `yarn link -p [path-to-local-cypher-builder]` 17 | 18 | To unlink, in the project using cypher-builder: 19 | 20 | - `yarn unlink @neo4j/cypher-builder` 21 | 22 | # TSDoc references 23 | 24 | Each public element of the library should have a TSDoc comment compatible with [TypeDoc](https://typedoc.org/guides/overview). 25 | The comments should follow these conventions: 26 | 27 | - Brief description 28 | - @group - This should be the Cypher concept related to this interface. Cypher Functions, Clauses, Operators, Procedures, Other Expressions. 29 | - @see {@link https://neo4j.com/docs/cypher-manual | Cypher Documentation} - A link to the element in the Cypher documentation 30 | - @internal - If used by the library and not exposed 31 | - @example - example of usage and resulting Cypher 32 | 33 | ```` 34 | * @example 35 | * ```ts 36 | * new Cypher.Match(new Node({labels: ["Movie"]})).optional(); 37 | * ``` 38 | * _Cypher:_ 39 | * ```cypher 40 | * OPTIONAL MATCH (this:Movie) 41 | * ``` 42 | ```` 43 | 44 | ## Files 45 | 46 | - `tsdoc.json` Defines the tsdoc shcema 47 | - `typedoc.json` Configures the tool typedoc 48 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Cypher Builder 2 | 3 | [![npm version](https://badge.fury.io/js/@neo4j%2Fcypher-builder.svg)](https://www.npmjs.com/package/@neo4j/cypher-builder) 4 | [![Test](https://github.com/neo4j/cypher-builder/actions/workflows/test.yml/badge.svg)](https://github.com/neo4j/cypher-builder/actions/workflows/test.yml) 5 | [![Lint](https://github.com/neo4j/cypher-builder/actions/workflows/lint.yml/badge.svg)](https://github.com/neo4j/cypher-builder/actions/workflows/lint.yml) 6 | 7 | Cypher Builder is a JavaScript programmatic API to create [Cypher](https://neo4j.com/docs/cypher-manual/current/) queries for [Neo4j](https://neo4j.com/). 8 | 9 | - [Documentation](https://neo4j.github.io/cypher-builder/cypher-builder/current/) 10 | 11 | ```typescript 12 | import Cypher from "@neo4j/cypher-builder"; 13 | 14 | const movieNode = new Cypher.Node(); 15 | const pattern = new Cypher.Pattern(movieNode, { labels: ["Movie"] }); 16 | 17 | const matchQuery = new Cypher.Match(pattern) 18 | .where(movieNode, { 19 | title: new Cypher.Param("The Matrix"), 20 | }) 21 | .return(movieNode.property("title")); 22 | 23 | const { cypher, params } = matchQuery.build(); 24 | 25 | console.log(cypher); 26 | console.log(params); 27 | ``` 28 | 29 | _Cypher_ 30 | 31 | ```cypher 32 | MATCH (this0:Movie) 33 | WHERE this0.title = $param0 34 | RETURN this0.title 35 | ``` 36 | 37 | _Params_ 38 | 39 | ```typescript 40 | { 41 | "param0": "The Matrix", 42 | } 43 | ``` 44 | 45 | # Examples 46 | 47 | You can find usage examples in the [examples](https://github.com/neo4j/cypher-builder/tree/main/examples) folder. 48 | 49 | > This library is for JavaScript and TypeScript only. If you are using Java, check [Neo4j Cypher DSL](https://neo4j.github.io/cypher-dsl). 50 | -------------------------------------------------------------------------------- /addlicense: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | -------------------------------------------------------------------------------- /docs/.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | *.ipr 3 | *.iws 4 | *.sw? 5 | *~ 6 | .DS_Store 7 | .cache 8 | .cache-main 9 | .cache-main 10 | .cache-main 11 | .cache-tests 12 | .cache-tests 13 | .cache-tests 14 | .classpath 15 | .externalToolBuilders/ 16 | .factorypath 17 | .gradle 18 | .gradletasknamecache 19 | .idea 20 | .java-version 21 | .mailmap 22 | .project 23 | .scala_dependencies 24 | .settings 25 | .shell_history 26 | Thumbs.db 27 | \#* 28 | bin/teamcity/ 29 | build/ 30 | devenv.local 31 | shared/ 32 | src/main/_common-and-old/ 33 | tags 34 | target/ 35 | 36 | # node modules 37 | node_modules/ 38 | .env 39 | -------------------------------------------------------------------------------- /docs/README.adoc: -------------------------------------------------------------------------------- 1 | = Cypher Builder Documentation 2 | 3 | 4 | == Prereqs 5 | 6 | - link:https://nodejs.org/en/download/[Node.js] 7 | - npm 8 | 9 | == Installation 10 | 11 | To install the required packages: 12 | 13 | ---- 14 | npm i 15 | ---- 16 | 17 | == Generating HTML output 18 | 19 | To convert asciidoc source to HTML: 20 | 21 | ---- 22 | npm run build 23 | ---- 24 | 25 | == Viewing HTML output 26 | 27 | To view the built site, launch a local server: 28 | 29 | 1. `npm start` 30 | 2. In a browser tab, go to `localhost:8000` 31 | 32 | == Live preview 33 | 34 | When you run `npm start`, the project is monitored for updates to asciidoc files. 35 | 36 | If a change to an asciidoc file is detected the site is automatically rebuilt. 37 | -------------------------------------------------------------------------------- /docs/antora.yml: -------------------------------------------------------------------------------- 1 | name: cypher-builder 2 | title: Cypher Builder 3 | version: "current" 4 | # display_version: '1.0-preview' 5 | start_page: ROOT:index.adoc 6 | nav: 7 | - modules/ROOT/content-nav.adoc 8 | -------------------------------------------------------------------------------- /docs/modules/ROOT/content-nav.adoc: -------------------------------------------------------------------------------- 1 | * xref:index.adoc[] 2 | * Getting started 3 | ** xref:getting-started/installation.adoc[] 4 | ** xref:getting-started/querying.adoc[] 5 | ** xref:getting-started/filters-and-projections.adoc[] 6 | ** xref:getting-started/relationships-and-advanced-filtering.adoc[] 7 | ** xref:getting-started/connecting-to-neo4j.adoc[] 8 | * Clauses 9 | ** xref:clauses/match.adoc[] 10 | ** xref:clauses/create.adoc[] 11 | ** xref:clauses/return.adoc[] 12 | ** xref:clauses/merge.adoc[] 13 | ** xref:clauses/with.adoc[] 14 | ** xref:clauses/set.adoc[] 15 | ** xref:clauses/union.adoc[] 16 | ** xref:clauses/unwind.adoc[] 17 | ** xref:clauses/foreach.adoc[] 18 | ** xref:clauses/load-csv.adoc[] 19 | ** xref:clauses/use.adoc[] 20 | * Variables and parameters 21 | ** xref:variables-and-params/variables.adoc[] 22 | ** xref:variables-and-params/parameters.adoc[] 23 | ** xref:variables-and-params/literals.adoc[] 24 | ** xref:variables-and-params/aliasing.adoc[] 25 | ** xref:variables-and-params/maps.adoc[] 26 | ** xref:variables-and-params/lists.adoc[] 27 | * xref:patterns.adoc[] 28 | * xref:functions.adoc[] 29 | * xref:procedures.adoc[] 30 | * Subqueries 31 | ** xref:subqueries/call.adoc[] 32 | ** xref:subqueries/exists.adoc[] 33 | ** xref:subqueries/count.adoc[] 34 | ** xref:subqueries/collect.adoc[] 35 | * How-to guides 36 | ** xref:how-to/concatenate-clauses.adoc[] 37 | ** xref:how-to/customize-cypher.adoc[] 38 | ** xref:how-to/conditional-expressions.adoc[] 39 | ** xref:how-to/use-change-data-capture.adoc[] 40 | ** xref:how-to/type-predicate-expressions.adoc[] 41 | ** xref:how-to/filter-by-labels.adoc[] 42 | ** xref:how-to/update-labels.adoc[] 43 | ** xref:how-to/define-cypher-version.adoc[] 44 | * xref:compatibility.adoc[] 45 | * xref:migration-guide-2.adoc[] 46 | * link:https://github.com/neo4j/cypher-builder/tree/main/examples[Examples] 47 | * link:https://neo4j.github.io/cypher-builder/reference/[Reference] 48 | -------------------------------------------------------------------------------- /docs/modules/ROOT/pages/clauses/foreach.adoc: -------------------------------------------------------------------------------- 1 | [[foreach]] 2 | :description: This page describes how to create `FOREACH` clauses. 3 | = Foreach 4 | 5 | This page describes how to create a link:https://neo4j.com/docs/cypher-manual/current/clauses/foreach/[`FOREACH`] clause using the `Cypher.Foreach` class. 6 | 7 | A `Foreach` clause takes a single variable to be used in a loop. The methods `.in` and `.do` are used to defined the list and update clauses: 8 | 9 | [source, javascript] 10 | ---- 11 | const x = new Cypher.Variable(); 12 | const query = new Cypher.Foreach(x).in(new Cypher.Param([1, 2, 3])).do( 13 | new Cypher.Create( 14 | new Cypher.Pattern({ 15 | labels: ["Movie"], 16 | properties: { 17 | id: x, 18 | }, 19 | }) 20 | ) 21 | ); 22 | ---- 23 | 24 | 25 | [source, cypher] 26 | ---- 27 | FOREACH (var0 IN $param0 | 28 | CREATE (:Movie { id: var0 }) 29 | ) 30 | ---- 31 | 32 | -------------------------------------------------------------------------------- /docs/modules/ROOT/pages/clauses/load-csv.adoc: -------------------------------------------------------------------------------- 1 | [[load-csv]] 2 | :description: This page describes how to create `LOAD CSV` clauses. 3 | = Load CSV 4 | 5 | This page describes how to create link:https://neo4j.com/docs/cypher-manual/current/clauses/load-csv/[`LOAD CSV`] clauses in Cypher with Cypher Builder. To achieve this, use the `LoadCSV` class: 6 | 7 | [source, javascript] 8 | ---- 9 | const row = new Cypher.Variable(); 10 | const loadCSV = new Cypher.LoadCSV("https://data.neo4j.com/bands/artists.csv", row).return(row); 11 | ---- 12 | 13 | [source, cypher] 14 | ---- 15 | LOAD CSV FROM "https://data.neo4j.com/bands/artists.csv" AS var0 16 | RETURN var0 17 | ---- 18 | -------------------------------------------------------------------------------- /docs/modules/ROOT/pages/clauses/merge.adoc: -------------------------------------------------------------------------------- 1 | [[merge]] 2 | :description: This page describes how to create `MERGE` clauses. 3 | = Merge 4 | 5 | This page describes how to create a link:https://neo4j.com/docs/cypher-manual/current/clauses/merge/[`MERGE`] clause with the `Cypher.Merge` class. 6 | 7 | To create a `Merge` clause, first create a valid pattern using the xref:/patterns.adoc[Pattern] class and pass it to `Merge` constructor: 8 | 9 | 10 | [source, javascript] 11 | ---- 12 | const movie = new Cypher.Node(); 13 | const actor = new Cypher.Node(); 14 | const pattern = new Cypher.Pattern(movie, { labels: ["Movie"] }).related({type: ["ACTED_IN"]}).to(actor); 15 | 16 | const mergeQuery = new Cypher.Merge(pattern); 17 | const { cypher, params } = matchQuery.build() 18 | ---- 19 | 20 | This generates the following `MERGE` clause: 21 | 22 | [source, cypher] 23 | ---- 24 | MERGE (this:Movie)-[:ACTED_IN]->(this1) 25 | ---- 26 | 27 | Afterwards, other clauses can be added. For example: 28 | 29 | [source, javascript] 30 | ---- 31 | const mergeQuery = new Cypher.Merge(pattern) 32 | .where(Cypher.eq(movie.property("name"), new Cypher.Param("my-movie"))) 33 | .return(movie); 34 | ---- 35 | 36 | [source, cypher] 37 | ---- 38 | MERGE (this:Movie)-[:ACTED_IN]->(this1) 39 | WHERE this.name = $param1 40 | return this 41 | ---- 42 | 43 | == On Create / On Match 44 | 45 | A `MERGE` statement can be followed by `ON CREATE SET` and `ON MATCH SET`, this can be achieved with the methods `onCreateSet` and `onMatchSet` respectively: 46 | 47 | [source, javascript] 48 | ---- 49 | const node = new Cypher.Node(); 50 | 51 | const countProp = node.property("count"); 52 | const query = new Cypher.Merge( 53 | new Cypher.Pattern(node, { 54 | labels: ["MyLabel"], 55 | }) 56 | ) 57 | .onCreateSet([countProp, new Cypher.Literal(1)]) 58 | .onMatchSet([countProp, Cypher.plus(countProp, new Cypher.Literal(1))]); 59 | ---- 60 | 61 | [source, cypher] 62 | ---- 63 | MERGE (this0:MyLabel) 64 | ON MATCH SET 65 | this0.count = (this0.count + 1) 66 | ON CREATE SET 67 | this0.count = 1 68 | ---- 69 | -------------------------------------------------------------------------------- /docs/modules/ROOT/pages/clauses/return.adoc: -------------------------------------------------------------------------------- 1 | [[return]] 2 | :description: This page describes how to create `RETURN` clauses. 3 | = Return 4 | 5 | This page describes how to create a link:https://neo4j.com/docs/cypher-manual/current/clauses/return/[`RETURN`] clause with the `Cypher.Return` class. 6 | 7 | Return clauses can be created with `new Cypher.Return`, but more commonly they are created after an existing clause, such as `MATCH`, by using the method `.return`. 8 | In both cases, the return variables can be passed as parameters: 9 | 10 | [source, javascript] 11 | ---- 12 | const node = new Cypher.Node(); 13 | const returnQuery = new Cypher.Return(node, new Cypher.Literal(10)); 14 | ---- 15 | 16 | This generates the following `RETURN` clause: 17 | 18 | [source, cypher] 19 | ---- 20 | RETURN this0, 10 21 | ---- 22 | 23 | Any expression can be passed to return, for example a function: 24 | 25 | [source, javascript] 26 | ---- 27 | const returnQuery = new Cypher.Return(Cypher.round(new Cypher.Param(2.3))); 28 | ---- 29 | 30 | Which translates to: 31 | 32 | [source, cypher] 33 | ---- 34 | RETURN round($param1) 35 | ---- 36 | 37 | ## Aliasing results 38 | 39 | Results can be aliased by using an array with two elements - the variable and the aliased name, which can be a string or a variable: 40 | 41 | [source, javascript] 42 | ---- 43 | const node = new Cypher.Node(); 44 | const returnQuery = new Cypher.Return([node, "my-node"]); 45 | ---- 46 | 47 | This generates the following clause: 48 | 49 | [source, cypher] 50 | ---- 51 | RETURN this0 AS my-node 52 | ---- 53 | 54 | ## Unique results 55 | 56 | `DISTINCT` can be added to `RETURN` by using the `.distinct` method: 57 | 58 | [source, javascript] 59 | ---- 60 | const returnQuery = new Cypher.Return(node).distinct(); 61 | ---- 62 | 63 | This generates the following clause: 64 | 65 | [source, cypher] 66 | ---- 67 | RETURN DISTINCT this0 68 | ---- 69 | 70 | -------------------------------------------------------------------------------- /docs/modules/ROOT/pages/clauses/unwind.adoc: -------------------------------------------------------------------------------- 1 | [[unwind]] 2 | :description: This page describes how to create `UNWIND` clauses. 3 | = Unwind 4 | 5 | This page describes how to create a link:https://neo4j.com/docs/cypher-manual/current/clauses/unwind/[`UNWIND`] clause with the `Cypher.Unwind` class. 6 | 7 | To create an `Unwind` clause, pass a tuple of a variable or expression and its alias to `new Cypher.Unwind`: 8 | 9 | 10 | [source, javascript] 11 | ---- 12 | const val = new Cypher.Variable() 13 | const unwindClause = new Cypher.Unwind([new Cypher.Param([1,2]), val]).return([val, "result"]) 14 | 15 | const { cypher, params } = unwindClause.build() 16 | ---- 17 | 18 | This generates the following `UNWIND` clause: 19 | 20 | [source, cypher] 21 | ---- 22 | UNWIND $param0 AS var0 23 | RETURN var0 AS result 24 | ---- 25 | -------------------------------------------------------------------------------- /docs/modules/ROOT/pages/clauses/use.adoc: -------------------------------------------------------------------------------- 1 | [[use]] 2 | :description: This page describes how to create `USE` clauses. 3 | = Use 4 | 5 | This page describes how to create a link:https://neo4j.com/docs/cypher-manual/current/clauses/use/[`USE`] clause with the `Cypher.Use` class. 6 | 7 | To create an `Use` clause, you can pass an existing query to `Cypher.use` to prepend an `USE` statement before the query: 8 | 9 | 10 | [source, javascript] 11 | ---- 12 | const n = new Cypher.Node(); 13 | const query = new Cypher.Match(new Cypher.Pattern(n, { labels: ["Movie"] })).return(n); 14 | 15 | const useQuery = new Cypher.Use("mydb", query); 16 | ---- 17 | 18 | This generates the following query: 19 | 20 | [source, cypher] 21 | ---- 22 | USE mydb 23 | MATCH (this0:Movie) 24 | RETURN this0 25 | ---- 26 | -------------------------------------------------------------------------------- /docs/modules/ROOT/pages/clauses/with.adoc: -------------------------------------------------------------------------------- 1 | [[with]] 2 | :description: This page describes how to create `WITH` clauses. 3 | = With 4 | 5 | This page describes how to create a link:https://neo4j.com/docs/cypher-manual/current/clauses/with/[`WITH`] clause using the `Cypher.With` class. Note that this is different to the xref:../subqueries/call.adoc#_importwith[ImportWith] statement inside `CALL`. 6 | 7 | A `With` clause will take multiple parameters. Variables can be passed directly without aliasing: 8 | 9 | [source, javascript] 10 | ---- 11 | const movie = new Cypher.Node(); 12 | const withClause = new Cypher.With(movie); 13 | ---- 14 | 15 | [source, cypher] 16 | ---- 17 | WITH this0 18 | ---- 19 | 20 | 21 | == Aliasing 22 | 23 | Any expression can be passed to `With` and aliased to a `Variable` to be used later in the query by passing a tuple of an expression and the aliaed variable: 24 | 25 | [source, javascript] 26 | ---- 27 | const variable = new Cypher.Variable(); 28 | new Cypher.With([new Cypher.Literal("Hello"), variable]); 29 | ---- 30 | 31 | [source, cypher] 32 | ---- 33 | WITH "Hello" AS var0 34 | ---- 35 | 36 | A string can be used directly as the alias value, when the name is already known. 37 | 38 | [source, javascript] 39 | ---- 40 | new Cypher.With([new Cypher.Literal("Hello"), "myVar"]); 41 | ---- 42 | 43 | [source, cypher] 44 | ---- 45 | WITH "Hello" AS myVar 46 | ---- 47 | 48 | == Wildcard 49 | 50 | 51 | `With` accepts the string `"*"` to add a wildcard to carry over all existing variables. This parameter cannot be aliased, and will always be added at the beginning of the `WITH` statement: 52 | 53 | 54 | [source, javascript] 55 | ---- 56 | new Cypher.With("*", [movieNode, "result"]); 57 | ---- 58 | 59 | [source, cypher] 60 | ---- 61 | WITH *, this0 AS result 62 | ---- 63 | -------------------------------------------------------------------------------- /docs/modules/ROOT/pages/compatibility.adoc: -------------------------------------------------------------------------------- 1 | [[compatibility]] 2 | :description: This page outlines the compatibility requirements for `@neo4j/cypher-builder` version 2 with Cypher and Node.js. 3 | = Compatibility 4 | 5 | This page outlines the compatibility requirements for `@neo4j/cypher-builder` version 2 with Cypher and Node.js. 6 | 7 | * Targets link:https://neo4j.com/docs/cypher-manual/5/introduction/[Cypher 5], with support for link:https://neo4j.com/docs/cypher-manual/4.4/introduction/[Cypher 4.4]. 8 | * Compatible with Node.js version 16.0.0 and later. 9 | 10 | [NOTE] 11 | ==== 12 | `@neo4j/cypher-builder` version 1 is no longer supported. Version 2 is a full replacement and maintains the same compatibility with Cypher and Node.js. 13 | ==== 14 | -------------------------------------------------------------------------------- /docs/modules/ROOT/pages/getting-started/installation.adoc: -------------------------------------------------------------------------------- 1 | [[installation]] 2 | :description: This guide shows how to start using Cypher Builder. 3 | = Installation 4 | 5 | This guide shows how to start using Cypher Builder by setting up a Node.js project with `@neo4j/cypher-builder`. 6 | 7 | == Requirements 8 | 9 | * link:https://nodejs.org/[Node.js] 16.0.0 or greater 10 | * link:https://docs.npmjs.com/downloading-and-installing-node-js-and-npm[npm] 11 | * **[Optional]** A link:https://neo4j.com/cloud/platform/aura-graph-database/?ref=nav-get-started-cta[Neo4j] database to try Cypher queries. 12 | 13 | == Instructions 14 | 15 | . In a folder of your choice, run the following command to create a Node.js project and a `package.json` file: 16 | + 17 | [source, bash] 18 | ---- 19 | npm init es6 -y 20 | ---- 21 | + 22 | Note that these examples use ES6 modules, but CommonJS modules can be used as well. 23 | 24 | 25 | . Install link:https://www.npmjs.com/package/@neo4j/cypher-builder[`@neo4j/cypher-builder`] and add it to the dependencies list with the following command: 26 | + 27 | [source, cmd] 28 | ---- 29 | npm install --save @neo4j/cypher-builder 30 | ---- 31 | 32 | . Create a new file `main.js` with the following content: 33 | + 34 | [source, javascript] 35 | ---- 36 | import Cypher from "@neo4j/cypher-builder"; 37 | ---- 38 | 39 | . Execute the script: 40 | + 41 | [source, bash] 42 | ---- 43 | node main.js 44 | ---- 45 | + 46 | At this point, the script should not do anything, but if it doesn't show an error it means Cypher Builder has been correctly installed. 47 | -------------------------------------------------------------------------------- /docs/modules/ROOT/pages/how-to/conditional-expressions.adoc: -------------------------------------------------------------------------------- 1 | [[conditional-expressions]] 2 | :description: This page describes how to create conditional expressions with CASE. 3 | = Conditional expressions (`CASE`) 4 | 5 | This page describes how to create link:https://neo4j.com/docs/cypher-manual/current/queries/case/[`CASE`] expressions in Cypher with Cypher Builder. 6 | 7 | 8 | == Simple CASE 9 | 10 | The simple `CASE` form compares a single expressions against multiple values. It can be constructed with the `Case` class by passing the expression to be compared the constructor: 11 | 12 | 13 | [source, javascript] 14 | ---- 15 | const person = new Cypher.Node(); 16 | new Cypher.Case(person.property("eyes")) 17 | .when(new Cypher.Literal("blue")).then(new Cypher.Literal(1)) 18 | .when(new Cypher.Literal("brown"), new Cypher.Literal("hazel")).then(new Cypher.Literal(2)) 19 | .else(new Cypher.Literal(3)) 20 | ---- 21 | 22 | The resulting Cypher, note that `END` is added automatically: 23 | 24 | [source, cypher] 25 | ---- 26 | CASE n.eyes 27 | WHEN 'blue' THEN 1 28 | WHEN 'brown', 'hazel' THEN 2 29 | ELSE 3 30 | END 31 | ---- 32 | 33 | 34 | == Generic CASE 35 | 36 | The generic `CASE` expression with conditional statements can be constructed with the `Case` class by ignoring the constructor parameter: 37 | 38 | [source, javascript] 39 | ---- 40 | const person = new Cypher.Node(); 41 | new Cypher.Case() 42 | .when(Cypher.eq(person.property("eyes"), new Cypher.Literal("blue"))) 43 | .then(new Cypher.Literal(1)) 44 | .when(Cypher.lt(person.property("age"), new Cypher.Literal(40))) 45 | .then(new Cypher.Literal(2)) 46 | .else(new Cypher.Literal(3)) 47 | ---- 48 | 49 | The resulting Cypher, note that `END` is added automatically: 50 | 51 | [source, cypher] 52 | ---- 53 | CASE 54 | WHEN n.eyes = 'blue' THEN 1 55 | WHEN n.age < 40 THEN 2 56 | ELSE 3 57 | END 58 | ---- 59 | -------------------------------------------------------------------------------- /docs/modules/ROOT/pages/how-to/define-cypher-version.adoc: -------------------------------------------------------------------------------- 1 | [[define-cypher-version]] 2 | :description: This page describes how to define the Cypher version to be used in the query. 3 | = Define Cypher version 4 | 5 | It is possible to define the version of Cypher to use in a query by prepending that query with `CYPHER [version]`. For example: 6 | 7 | 8 | [source, cypher] 9 | ---- 10 | CYPHER 5 11 | MATCH (this0) 12 | RETURN this0 13 | ---- 14 | 15 | 16 | To add the Cypher version at the beggining of the query, pass the parameter `cypherVersion` to `.build`: 17 | 18 | [source, javascript] 19 | ---- 20 | const movieNode = new Cypher.Node(); 21 | const pattern = new Cypher.Pattern(movieNode, { labels: ["Movie"] }); 22 | 23 | const matchQuery = new Cypher.Match(pattern) 24 | .where(movieNode, { 25 | title: new Cypher.Param("The Matrix"), 26 | }) 27 | .return(movieNode.property("title")); 28 | 29 | const { cypher } = matchQuery.build({ 30 | cypherVersion: "5", 31 | }); 32 | ---- 33 | 34 | [source, cypher] 35 | ---- 36 | CYPHER 5 37 | MATCH (this0:Movie) 38 | WHERE this0.title = $param0 39 | RETURN this0.title 40 | ---- 41 | 42 | Note that this setting only prepends the `CYPHER` statement to the query. The query itself is unchanged. 43 | -------------------------------------------------------------------------------- /docs/modules/ROOT/pages/how-to/update-labels.adoc: -------------------------------------------------------------------------------- 1 | [[update-labels]] 2 | :description: This page describes how to add or remove labels to a node. 3 | = Update labels 4 | 5 | To add or remove labels to a node, use `.set` and `.remove` with the node method `.label`. 6 | 7 | == Add labels 8 | 9 | [source, javascript] 10 | ---- 11 | const movie = new Cypher.Node(); 12 | const clause = new Cypher.Match(new Cypher.Pattern(movie)).set(movie.label("NewLabel"), movie.label("Another label")); 13 | ---- 14 | 15 | 16 | [source, cypher] 17 | ---- 18 | MATCH (this0) 19 | SET 20 | this0:NewLabel, 21 | this0:`Another Label` 22 | ---- 23 | 24 | 25 | == Remove labels 26 | 27 | 28 | [source, javascript] 29 | ---- 30 | const movie = new Cypher.Node(); 31 | const clause = new Cypher.Match(new Cypher.Pattern(movie)).remove(movie.label("NewLabel")); 32 | ---- 33 | 34 | 35 | [source, cypher] 36 | ---- 37 | MATCH (this0) 38 | REMOVE this0:NewLabel 39 | ---- 40 | 41 | == Set dynamic labels 42 | 43 | In some cases, the labels to add or remove need to be defined dynamically, such as a result of an expression. To achieve this, the `.label` methods accepts an expression instead of a string. 44 | 45 | For example, to copy all the labels from one node to another, the function `labels()` can be used as the expression to `.label`: 46 | 47 | 48 | [source, javascript] 49 | ---- 50 | new Cypher.Match(new Cypher.Pattern(movie)).set(movie.label(Cypher.labels(anotherNode))); 51 | ---- 52 | 53 | This correctly applies the syntax for dynamic labels: 54 | 55 | [source, cypher] 56 | ---- 57 | MATCH (this0) 58 | SET 59 | this0:$(labels(this1)) 60 | ---- 61 | -------------------------------------------------------------------------------- /docs/modules/ROOT/pages/index.adoc: -------------------------------------------------------------------------------- 1 | [[cypher-builder-docs]] 2 | :description: This section covers all documentation for Cypher Builder. 3 | = Cypher Builder 4 | 5 | Cypher Builder is a programmatic API for building link:https://neo4j.com/docs/cypher-manual/[Cypher] queries for Neo4j in JavaScript and TypeScript. 6 | 7 | 8 | 9 | If you are using Java, check link:https://neo4j.github.io/cypher-dsl[Neo4j Cypher-DSL]. 10 | -------------------------------------------------------------------------------- /docs/modules/ROOT/pages/subqueries/collect.adoc: -------------------------------------------------------------------------------- 1 | [[collect]] 2 | :description: This page describes how to create COLLECT subqueries with the Cypher Builder. 3 | = `Collect` 4 | 5 | Cypher link:https://neo4j.com/docs/cypher-manual/current/subqueries/collect/[`COLLECT` subquery expressions] (not to confuse with the `collect()` function) can be created with `new Cypher.Collect()`. 6 | To do this, a valid query needs to be passed to `Collect`, for example: 7 | 8 | [source, javascript] 9 | ---- 10 | const dog = new Cypher.Node({ labels: ["Dog"] }); 11 | const person = new Cypher.Node({ labels: ["Person"] }); 12 | 13 | const subquery = new Cypher.Match( 14 | new Cypher.Pattern(person).related(new Cypher.Relationship({ type: "HAS_DOG" })).to(dog) 15 | ).return(dog.property("name")); 16 | 17 | const collectExpression = new Cypher.Collect(subquery) 18 | 19 | const match = new Cypher.Match(person) 20 | .where(Cypher.in(new Cypher.Literal("Ozzy"), collectExpression)) 21 | .return(person); 22 | ---- 23 | 24 | [source, cypher] 25 | ---- 26 | MATCH (this0:Person) 27 | WHERE "Ozzy" IN COLLECT { 28 | MATCH (this0:Person)-[this1:HAS_DOG]->(this2:Dog) 29 | RETURN this2.name 30 | } 31 | RETURN this0 32 | ---- 33 | -------------------------------------------------------------------------------- /docs/modules/ROOT/pages/subqueries/count.adoc: -------------------------------------------------------------------------------- 1 | [[count]] 2 | :description: This page describes how to create COUNT subqueries with the Cypher Builder. 3 | = `Count` 4 | 5 | Cypher link:https://neo4j.com/docs/cypher-manual/current/subqueries/count/[`COUNT` subqueries] can be created with `new Cypher.Count()`. 6 | To do this, a valid query needs to be passed to `Count`. 7 | 8 | Note that count subqueries can also be used as predicates in `WHERE` clauses. 9 | For example: 10 | 11 | [source, javascript] 12 | ---- 13 | const subquery = new Cypher.Match(new Cypher.Node({ labels: ["Movie"] })).return("*"); 14 | 15 | const countExpr = new Cypher.Count(subquery); 16 | const match = new Cypher.Match(new Cypher.Node()) 17 | .where(Cypher.gt(countExpr, new Cypher.Literal(10))) 18 | .return("*"); 19 | ---- 20 | 21 | [source, cypher] 22 | ---- 23 | MATCH (this0) 24 | WHERE COUNT { 25 | MATCH (this1:Movie) 26 | RETURN * 27 | } > 10 28 | RETURN * 29 | ---- 30 | -------------------------------------------------------------------------------- /docs/modules/ROOT/pages/subqueries/exists.adoc: -------------------------------------------------------------------------------- 1 | [[exists]] 2 | :description: This page describes how to create EXISTS subqueries with the Cypher Builder. 3 | = `Exists` 4 | 5 | Cypher link:https://neo4j.com/docs/cypher-manual/current/subqueries/existential/[`EXISTS` subqueries] can be created with `new Cypher.Exists()`. 6 | To do this, a valid query needs to be passed to `Exists`. 7 | 8 | Note that count subqueries can also be used as predicates in `WHERE` clauses, for example: 9 | 10 | [source, javascript] 11 | ---- 12 | const subquery = new Cypher.Match(new Cypher.Node({ labels: ["Movie"] })).return("*"); 13 | 14 | const existsExpression = new Cypher.Exists(subquery); 15 | const match = new Cypher.Match(new Cypher.Node()).where(existsExpression).return("*"); 16 | ---- 17 | 18 | [source, cypher] 19 | ---- 20 | MATCH (this0) 21 | WHERE EXISTS { 22 | MATCH (this1:Movie) 23 | RETURN * 24 | } 25 | RETURN * 26 | ---- 27 | -------------------------------------------------------------------------------- /docs/modules/ROOT/pages/variables-and-params/aliasing.adoc: -------------------------------------------------------------------------------- 1 | [[aliasing]] 2 | :description: This page describes how to do aliasing with Cypher Builder. 3 | = Aliasing 4 | 5 | Variables are commonly used for aliasing in a `WITH` or `RETURN` statement. 6 | To do that, you need to pass a tuple of the value and its alias. 7 | 8 | == Aliasing to a string 9 | This is how you should proceed when aliasing to a string: 10 | [source, javascript] 11 | ---- 12 | const node = new Cypher.Node({ 13 | labels: ["Movie"], 14 | }); 15 | const withQuery = new Cypher.With([node, "my-alias"]); 16 | ---- 17 | 18 | [source, cypher] 19 | ---- 20 | WITH this0 AS my-alias 21 | ---- 22 | 23 | == Aliasing to a variable 24 | 25 | Instead of an exact string, you can alias to a `Cypher.Variable` so it can be reused as any other variable: 26 | 27 | [source, javascript] 28 | ---- 29 | const movieNode = new Cypher.Node({ labels: ["Movie"] }); 30 | const myVar = new Cypher.Variable(); 31 | const match = new Cypher.Match(movieNode).with([movieNode, myVar]).return([myVar, "Film"]); 32 | ---- 33 | 34 | [source, cypher] 35 | ---- 36 | MATCH (this0:`Movie`) 37 | WITH this0 AS var1 38 | RETURN var1 AS Film 39 | ---- 40 | 41 | In the previous example, after a `MATCH` the node variable `this0` is aliased to a variable with an arbitrary name (`var1`) in a `WITH` statement. 42 | Finally, in the `RETURN` the variable is aliased to the specific name `Film` that will be returned. 43 | 44 | -------------------------------------------------------------------------------- /docs/modules/ROOT/pages/variables-and-params/literals.adoc: -------------------------------------------------------------------------------- 1 | [[literals]] 2 | :description: This page shows how to add literal values in Cypher Builder. 3 | = Literals 4 | 5 | Literal values can be defined with `Cypher.Literal`. 6 | Literals behave like parameters, but they will inject the value provided directly into the Cypher, serializing it as needed. 7 | For instance: 8 | 9 | [source, javascript] 10 | ---- 11 | const movie = new Cypher.Node(); 12 | const titleProp = movie.property(movie); 13 | const titleLiteral = new Cypher.Literal("The Matrix") 14 | 15 | const query = new Cypher.Match(new Cypher.Pattern(movie, { labels: ["Movie"] })).where(Cypher.eq(titleProp, titleLiteral)).return(titleLiteral); 16 | 17 | const {cypher, params} = query.build(); 18 | ---- 19 | 20 | .Cypher 21 | [source, cypher] 22 | ---- 23 | MATCH (this0:Movie) 24 | WHERE this0[this0] = "The Matrix" 25 | RETURN this0, "The Matrix" 26 | ---- 27 | 28 | .Params 29 | [source, javascript] 30 | ---- 31 | { } 32 | ---- 33 | 34 | Note how the value `The Matrix` is not injected directly, but correctly serialized to a string in Cypher. 35 | 36 | The following values are supported by `Literal`: 37 | 38 | * *String:* `Cypher.Literal("Hello")` -> `"Hello"` 39 | * *Number:* `Cypher.Literal(5)` -> `5` 40 | * *Boolean:* `Cypher.Literal(true)` -> `true` 41 | * *Array:* `Cypher.Literal([5, "Hello"])` -> `[5, "Hello"]` 42 | * *Null:* `Cypher.Literal(null)` -> `NULL` 43 | 44 | 45 | [NOTE] 46 | ==== 47 | It is generally recommended to use `Cypher.Param` rather than `Cypher.Literal` for user input. 48 | ==== 49 | 50 | == `NULL` 51 | 52 | As a shortcut for `new Cypher.Literal(null)`, the constant `Cypher.Null` is available. 53 | This will be translated to `NULL`: 54 | 55 | [source, javascript] 56 | ---- 57 | new Cypher.Return(Cypher.Null) 58 | ---- 59 | 60 | [source, cypher] 61 | ---- 62 | RETURN NULL 63 | ---- 64 | -------------------------------------------------------------------------------- /docs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "docs-template", 3 | "version": "1.0.0", 4 | "description": "Template repo for Neo4j documentation projects", 5 | "main": "server.js", 6 | "private": true, 7 | "scripts": { 8 | "start": "nodemon -e adoc --exec \"npm run build && npm run serve\"", 9 | "serve": "node server.js", 10 | "build": "antora preview.yml --stacktrace --log-format=pretty", 11 | "build-verify": "antora --stacktrace --fetch preview.yml --log-format=json --log-level=info --log-file ./build/log/log.json", 12 | "publish-verify": "antora --stacktrace --fetch publish.yml --log-format=json --log-file ./build/log/log.json" 13 | }, 14 | "keywords": [ 15 | "antora", 16 | "neo4j" 17 | ], 18 | "author": "Neo4j", 19 | "license": "ISC", 20 | "dependencies": { 21 | "@antora/cli": "^3.1.10", 22 | "@antora/site-generator-default": "^3.1.10", 23 | "@neo4j-antora/antora-add-notes": "^0.3.2", 24 | "@neo4j-antora/antora-modify-sitemaps": "^0.7.1", 25 | "@neo4j-antora/antora-page-roles": "^0.3.2", 26 | "@neo4j-antora/antora-table-footnotes": "^0.3.3", 27 | "@neo4j-antora/mark-terms": "1.1.0", 28 | "@neo4j-documentation/macros": "^1.0.4", 29 | "@neo4j-documentation/remote-include": "^1.0.0" 30 | }, 31 | "devDependencies": { 32 | "express": "^5.1.0", 33 | "nodemon": "^3.1.9" 34 | }, 35 | "overrides": { 36 | "@antora/site-generator-default": { 37 | "glob-parent": "6.0.2" 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /docs/preview.yml: -------------------------------------------------------------------------------- 1 | site: 2 | title: Cypher Builder docs 3 | url: https://neo4j.github.io/cypher-builder/ 4 | start_page: cypher-builder:ROOT:index.adoc 5 | 6 | content: 7 | sources: 8 | - url: ../ 9 | start_path: docs 10 | branches: HEAD 11 | exclude: 12 | - "!**/_includes/*" 13 | - "!**/readme.adoc" 14 | - "!**/README.adoc" 15 | 16 | ui: 17 | bundle: 18 | url: https://static-content.neo4j.com/build/ui-bundle-latest.zip 19 | snapshot: true 20 | output_dir: /assets 21 | 22 | urls: 23 | html_extension_style: indexify 24 | 25 | antora: 26 | extensions: 27 | - require: "@neo4j-antora/antora-modify-sitemaps" 28 | sitemap_version: "current" 29 | sitemap_loc_version: "current" 30 | move_sitemaps_to_components: true 31 | 32 | asciidoc: 33 | extensions: 34 | - "@neo4j-documentation/remote-include" 35 | - "@neo4j-documentation/macros" 36 | - "@neo4j-antora/antora-add-notes" 37 | - "@neo4j-antora/antora-page-roles" 38 | - "@neo4j-antora/antora-table-footnotes" 39 | - "@neo4j-antora/mark-terms" 40 | attributes: 41 | page-theme: docs 42 | page-type: Docs 43 | page-search-type: Docs 44 | page-search-site: Reference Docs 45 | page-canonical-root: /docs 46 | page-terms-to-mark: Cypher 47 | page-pagination: true 48 | page-no-canonical: true 49 | page-origin-private: true 50 | page-hide-toc: false 51 | # page-mixpanel: 4bfb2414ab973c741b6f067bf06d5575 52 | includePDF: false 53 | nonhtmloutput: "" 54 | experimental: "" 55 | copyright: 2022 56 | common-license-page-uri: https://neo4j.com/docs/license/ 57 | check-mark: icon:check[] 58 | cross-mark: icon:times[] 59 | neo4j-base-uri: https://neo4j.com 60 | neo4j-docs-base-uri: https://neo4j.com/docs 61 | -------------------------------------------------------------------------------- /docs/publish.yml: -------------------------------------------------------------------------------- 1 | site: 2 | title: Cypher Builder docs 3 | url: https://neo4j.github.io/cypher-builder/ 4 | start_page: cypher-builder:ROOT:index.adoc 5 | 6 | content: 7 | sources: 8 | - url: https://github.com/neo4j/cypher-builder.git 9 | branches: 10 | - main 11 | start_path: docs 12 | include: docs 13 | exclude: 14 | - "!**/_includes/*" 15 | - "!**/readme.adoc" 16 | - "!**/README.adoc" 17 | 18 | ui: 19 | bundle: 20 | url: https://static-content.neo4j.com/build/ui-bundle-latest.zip 21 | snapshot: true 22 | output_dir: /assets 23 | 24 | urls: 25 | html_extension_style: indexify 26 | 27 | antora: 28 | extensions: 29 | - require: "@neo4j-antora/antora-modify-sitemaps" 30 | sitemap_version: "current" 31 | sitemap_loc_version: "current" 32 | move_sitemaps_to_components: true 33 | 34 | asciidoc: 35 | extensions: 36 | - "@neo4j-documentation/remote-include" 37 | - "@neo4j-documentation/macros" 38 | - "@neo4j-antora/antora-add-notes" 39 | - "@neo4j-antora/antora-page-roles" 40 | - "@neo4j-antora/antora-table-footnotes" 41 | - "@neo4j-antora/mark-terms" 42 | attributes: 43 | page-theme: docs 44 | page-type: Docs 45 | page-search-type: Docs 46 | page-search-site: Reference Docs 47 | page-canonical-root: /docs 48 | page-terms-to-mark: Cypher 49 | page-pagination: true 50 | page-no-canonical: true 51 | page-origin-private: true 52 | page-hide-toc: false 53 | # page-mixpanel: 4bfb2414ab973c741b6f067bf06d5575 54 | includePDF: false 55 | nonhtmloutput: "" 56 | experimental: "" 57 | copyright: 2022 58 | common-license-page-uri: https://neo4j.com/docs/license/ 59 | check-mark: icon:check[] 60 | cross-mark: icon:times[] 61 | neo4j-base-uri: "" 62 | neo4j-docs-base-uri: /docs 63 | -------------------------------------------------------------------------------- /docs/server.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | 3 | const app = express(); 4 | app.use(express.static("./build/site")); 5 | 6 | app.use("/static/assets", express.static("./build/site/assets")); 7 | 8 | app.get("/", (req, res) => res.redirect("/docs/")); 9 | 10 | app.listen(8000, () => console.log("📘 http://localhost:8000")); 11 | -------------------------------------------------------------------------------- /eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import { FlatCompat } from "@eslint/eslintrc"; 2 | import js from "@eslint/js"; 3 | import typescriptEslint from "@typescript-eslint/eslint-plugin"; 4 | import tsParser from "@typescript-eslint/parser"; 5 | import tsdoc from "eslint-plugin-tsdoc"; 6 | import globals from "globals"; 7 | import path from "node:path"; 8 | import { fileURLToPath } from "node:url"; 9 | 10 | const __filename = fileURLToPath(import.meta.url); 11 | const __dirname = path.dirname(__filename); 12 | const compat = new FlatCompat({ 13 | baseDirectory: __dirname, 14 | recommendedConfig: js.configs.recommended, 15 | allConfig: js.configs.all, 16 | }); 17 | 18 | export default [ 19 | { 20 | ignores: ["**/dist", "**/docs", "**/coverage", "**/examples", "**/jest.config.js", "eslint.config.mjs"], 21 | }, 22 | ...compat.extends( 23 | "eslint:recommended", 24 | "plugin:@typescript-eslint/recommended-type-checked", 25 | "plugin:@typescript-eslint/recommended", 26 | "prettier" 27 | ), 28 | { 29 | plugins: { 30 | "@typescript-eslint": typescriptEslint, 31 | tsdoc, 32 | }, 33 | 34 | languageOptions: { 35 | globals: { 36 | ...globals.node, 37 | }, 38 | 39 | parser: tsParser, 40 | ecmaVersion: 5, 41 | sourceType: "commonjs", 42 | 43 | parserOptions: { 44 | projectService: true, 45 | }, 46 | }, 47 | 48 | rules: { 49 | "@typescript-eslint/no-unsafe-declaration-merging": "off", 50 | "@typescript-eslint/prefer-readonly": "error", 51 | 52 | "@typescript-eslint/consistent-type-imports": [ 53 | "error", 54 | { 55 | prefer: "type-imports", 56 | }, 57 | ], 58 | 59 | "tsdoc/syntax": "warn", 60 | }, 61 | }, 62 | ]; 63 | -------------------------------------------------------------------------------- /examples/README.md: -------------------------------------------------------------------------------- 1 | These examples construct Cypher queries and display the output Cypher and parameters. 2 | 3 | To run them: 4 | 5 | 1. `npm install` 6 | 2. `npm run build` 7 | 3. `ts-node examples/match.ts` 8 | -------------------------------------------------------------------------------- /examples/clauses/create.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import Cypher from "../../dist"; 21 | 22 | // CREATE (this0:Movie) 23 | // SET 24 | // this0.title = $param0, 25 | // this0.year = $param1 26 | // CREATE (this1:Movie) 27 | // SET 28 | // this1.title = $param0 29 | // CREATE (this2:Movie) 30 | // SET 31 | // this2 = { title: $param0, year: $param2 } 32 | 33 | const titleParam = new Cypher.Param("The Matrix"); 34 | 35 | const movie1 = new Cypher.Node(); 36 | const movie2 = new Cypher.Node(); 37 | const movie3 = new Cypher.Node(); 38 | 39 | // Note that both nodes share the same param 40 | const create1 = new Cypher.Create(new Cypher.Pattern(movie1, { labels: ["Movie"] })).set( 41 | [movie1.property("title"), titleParam], 42 | [movie1.property("year"), new Cypher.Param(1999)] 43 | ); 44 | const create2 = new Cypher.Create(new Cypher.Pattern(movie2, { labels: ["Movie"] })).set([ 45 | movie2.property("title"), 46 | titleParam, 47 | ]); 48 | 49 | const create3 = new Cypher.Create(new Cypher.Pattern(movie3, { labels: ["Movie"] })).set([ 50 | movie3, 51 | new Cypher.Map({ 52 | title: titleParam, 53 | year: new Cypher.Param(1999), 54 | }), 55 | ]); 56 | 57 | const { cypher, params } = Cypher.utils.concat(create1, create2, create3).build(); 58 | 59 | console.log("Cypher"); 60 | console.log(cypher); 61 | console.log("----"); 62 | console.log("Params", params); 63 | -------------------------------------------------------------------------------- /examples/clauses/foreach.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import console from "console"; 21 | import Cypher from "../../dist"; 22 | 23 | // FOREACH (var0 IN $param0 | 24 | // CREATE (:Movie { id: var0 }) 25 | // ) 26 | 27 | const x = new Cypher.Variable(); 28 | const query = new Cypher.Foreach(x).in(new Cypher.Param([1, 2, 3])).do( 29 | new Cypher.Create( 30 | new Cypher.Pattern({ 31 | labels: ["Movie"], 32 | properties: { 33 | id: x, 34 | }, 35 | }) 36 | ) 37 | ); 38 | 39 | const { cypher, params } = query.build(); 40 | 41 | console.log("Cypher"); 42 | console.log(cypher); 43 | console.log("----"); 44 | console.log("Params", params); 45 | -------------------------------------------------------------------------------- /examples/clauses/match.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import Cypher from "../../dist"; 21 | 22 | // MATCH (this1:`Person`)-[this0:ACTED_IN]->(this2:`Movie`) 23 | // WHERE (this1.name = $param0 AND this2.released = $param1) 24 | // RETURN this2.title, this2.released AS year 25 | 26 | const movieNode = new Cypher.Node(); 27 | const personNode = new Cypher.Node(); 28 | 29 | const actedInPattern = new Cypher.Pattern(movieNode, { labels: ["Movie"] }) 30 | .related({ type: "ACTED_IN" }) 31 | .to(personNode, { labels: ["Person"] }); 32 | 33 | const matchQuery = new Cypher.Match(actedInPattern) 34 | .where(personNode, { name: new Cypher.Param("Keanu Reeves") }) 35 | .and(movieNode, { released: new Cypher.Param(1999) }) 36 | .return(movieNode.property("title"), [movieNode.property("released"), "year"]); 37 | 38 | const { cypher, params } = matchQuery.build(); 39 | 40 | console.log("Cypher"); 41 | console.log(cypher); 42 | console.log("----"); 43 | console.log("Params", params); 44 | -------------------------------------------------------------------------------- /examples/clauses/merge.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import Cypher from "../../dist"; 21 | 22 | // MERGE (this0:MyLabel) 23 | // ON MATCH SET 24 | // this0.count = (this0.count + 1) 25 | // ON CREATE SET 26 | // this0.count = 1 27 | 28 | const node = new Cypher.Node(); 29 | 30 | const countProp = node.property("count"); 31 | const query = new Cypher.Merge( 32 | new Cypher.Pattern(node, { 33 | labels: ["MyLabel"], 34 | }) 35 | ) 36 | .onCreateSet([countProp, new Cypher.Literal(1)]) 37 | .onMatchSet([countProp, Cypher.plus(countProp, new Cypher.Literal(1))]); 38 | 39 | const { cypher, params } = query.build(); 40 | 41 | console.log("Cypher"); 42 | console.log(cypher); 43 | console.log("----"); 44 | console.log("Params", params); 45 | -------------------------------------------------------------------------------- /examples/clauses/union.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import Cypher from "../../dist"; 21 | 22 | // MATCH (this0:Actor) 23 | // RETURN this0.name AS name 24 | // UNION DISTINCT 25 | // MATCH (this0:Movie) 26 | // RETURN this0.title AS name 27 | 28 | const n = new Cypher.Node(); 29 | 30 | const match1 = new Cypher.Match(new Cypher.Pattern(n, { labels: ["Actor"] })).return([n.property("name"), "name"]); 31 | const match2 = new Cypher.Match(new Cypher.Pattern(n, { labels: ["Movie"] })).return([n.property("title"), "name"]); 32 | 33 | const union = new Cypher.Union(match1, match2).distinct(); 34 | 35 | const { cypher, params } = union.build(); 36 | 37 | console.log("Cypher"); 38 | console.log(cypher); 39 | console.log("----"); 40 | console.log("Params", params); 41 | -------------------------------------------------------------------------------- /examples/clauses/unwind.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import Cypher from "../../dist"; 21 | 22 | // UNWIND $param0 AS var0 23 | // WITH DISTINCT var0 24 | // RETURN collect(var0) AS setOfVals 25 | 26 | const coll = new Cypher.Variable(); 27 | 28 | const unwind = new Cypher.Unwind([new Cypher.Param([1, 2, 3, 4]), coll]) 29 | .with(coll) 30 | .distinct() 31 | .return([Cypher.collect(coll), "setOfVals"]); 32 | 33 | const { cypher, params } = unwind.build(); 34 | 35 | console.log("Cypher"); 36 | console.log(cypher); 37 | console.log("----"); 38 | console.log("Params", params); 39 | -------------------------------------------------------------------------------- /examples/clauses/use.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import Cypher from "../../dist"; 21 | 22 | // USE mydb 23 | // MATCH (this0:Movie) 24 | // RETURN this0 25 | 26 | const n = new Cypher.Node(); 27 | const query = new Cypher.Match(new Cypher.Pattern(n, { labels: ["Movie"] })).return(n); 28 | 29 | const useQuery = new Cypher.Use("mydb", query); 30 | const { cypher, params } = useQuery.build(); 31 | 32 | console.log("Cypher"); 33 | console.log(cypher); 34 | console.log("----"); 35 | console.log("Params", params); 36 | -------------------------------------------------------------------------------- /examples/clauses/with.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import Cypher from "../../dist"; 21 | 22 | // WITH *, this0 AS result 23 | 24 | const movieNode = new Cypher.Node(); 25 | 26 | const withStatement = new Cypher.With("*", [movieNode, "result"]); 27 | 28 | const { cypher, params } = withStatement.build(); 29 | 30 | console.log("Cypher"); 31 | console.log(cypher); 32 | console.log("----"); 33 | console.log("Params", params); 34 | -------------------------------------------------------------------------------- /examples/expressions/generic-case.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import Cypher from "../../dist"; 21 | 22 | // MATCH (this0:Person) 23 | // RETURN CASE 24 | // WHEN this0.eyes = "blue" THEN 1 25 | // WHEN this0.age < 40 THEN 2 26 | // ELSE 3 27 | // END AS eyeValue 28 | 29 | const person = new Cypher.Node(); 30 | const caseClause = new Cypher.Case() 31 | .when(Cypher.eq(person.property("eyes"), new Cypher.Literal("blue"))) 32 | .then(new Cypher.Literal(1)) 33 | .when(Cypher.lt(person.property("age"), new Cypher.Literal(40))) 34 | .then(new Cypher.Literal(2)) 35 | .else(new Cypher.Literal(3)); 36 | 37 | const query = new Cypher.Match(new Cypher.Pattern(person, { labels: ["Person"] })).return([caseClause, "eyeValue"]); 38 | 39 | const { cypher, params } = query.build(); 40 | 41 | console.log("Cypher"); 42 | console.log(cypher); 43 | console.log("----"); 44 | console.log("Params", params); 45 | -------------------------------------------------------------------------------- /examples/expressions/simple-case.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import Cypher from "../../dist"; 21 | 22 | // MATCH (this0:Person) 23 | // RETURN CASE this0.eyes 24 | // WHEN "blue" THEN 1 25 | // WHEN "brown", "hazel" THEN 2 26 | // ELSE 3 27 | // END AS eyeValue 28 | 29 | const person = new Cypher.Node(); 30 | const caseClause = new Cypher.Case(person.property("eyes")) 31 | .when(new Cypher.Literal("blue")) 32 | .then(new Cypher.Literal(1)) 33 | .when(new Cypher.Literal("brown"), new Cypher.Literal("hazel")) 34 | .then(new Cypher.Literal(2)) 35 | .else(new Cypher.Literal(3)); 36 | 37 | const query = new Cypher.Match(new Cypher.Pattern(person, { labels: ["Person"] })).return([caseClause, "eyeValue"]); 38 | 39 | const { cypher, params } = query.build(); 40 | 41 | console.log("Cypher"); 42 | console.log(cypher); 43 | console.log("----"); 44 | console.log("Params", params); 45 | -------------------------------------------------------------------------------- /examples/functions/trim.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import Cypher from "../.."; 21 | 22 | // RETURN trim(" Simple Trim "), trim(BOTH "x" FROM "xxxhelloxxx") 23 | 24 | // Using `trim()` with the simple syntax and the advanced trim expression 25 | const query = new Cypher.Return( 26 | Cypher.trim(new Cypher.Literal(" Simple Trim ")), 27 | Cypher.trim("BOTH", new Cypher.Literal("x"), new Cypher.Literal("xxxhelloxxx")) 28 | ); 29 | 30 | const { cypher, params } = query.build(); 31 | 32 | console.log("Cypher"); 33 | console.log(cypher); 34 | console.log("----"); 35 | console.log("Params", params); 36 | -------------------------------------------------------------------------------- /examples/patterns/label-expressions.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import Cypher from "../../dist"; 21 | 22 | // MATCH (this0:((Movie|Film)&!Show)) 23 | // RETURN this0 24 | 25 | const movieNode = new Cypher.Node(); 26 | 27 | const matchQuery = new Cypher.Match( 28 | new Cypher.Pattern(movieNode, { 29 | labels: Cypher.labelExpr.and(Cypher.labelExpr.or("Movie", "Film"), Cypher.labelExpr.not("Show")), 30 | }) 31 | ).return(movieNode); 32 | 33 | const { cypher, params } = matchQuery.build({ 34 | labelOperator: "&", 35 | }); 36 | 37 | console.log("Cypher"); 38 | console.log(cypher); 39 | console.log("----"); 40 | console.log("Params", params); 41 | -------------------------------------------------------------------------------- /examples/patterns/length.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import Cypher from "../../dist"; 21 | 22 | // MATCH (this0)-[this1:ACTED_IN*2..10]->() 23 | // RETURN this0 24 | 25 | const movie = new Cypher.Node(); 26 | const actedIn = new Cypher.Relationship(); 27 | 28 | const pattern = new Cypher.Pattern(movie).related(actedIn, { type: "ACTED_IN", length: { min: 2, max: 10 } }).to(); 29 | 30 | const matchQuery = new Cypher.Match(pattern).return(movie); 31 | 32 | const { cypher, params } = matchQuery.build({ 33 | labelOperator: "&", 34 | }); 35 | 36 | console.log("Cypher"); 37 | console.log(cypher); 38 | console.log("----"); 39 | console.log("Params", params); 40 | -------------------------------------------------------------------------------- /examples/patterns/quantified-path-patterns.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import Cypher from "../../dist"; 21 | 22 | // MATCH (this0:Movie { title: $param0 }) 23 | // ((:Movie)-[:ACTED_IN]->(:Person)){1,2} 24 | // (this1:Movie { title: $param1 }) 25 | // RETURN this1 26 | 27 | const m = new Cypher.Node(); 28 | const m2 = new Cypher.Node(); 29 | 30 | const quantifiedPath = new Cypher.QuantifiedPath( 31 | new Cypher.Pattern(m, { labels: ["Movie"], properties: { title: new Cypher.Param("V for Vendetta") } }), 32 | new Cypher.Pattern({ labels: ["Movie"] }) 33 | .related({ type: "ACTED_IN" }) 34 | .to({ labels: ["Person"] }) 35 | .quantifier({ min: 1, max: 2 }), 36 | new Cypher.Pattern(m2, { 37 | labels: ["Movie"], 38 | properties: { title: new Cypher.Param("Something's Gotta Give") }, 39 | }) 40 | ); 41 | 42 | const query = new Cypher.Match(quantifiedPath).return(m2); 43 | 44 | const { cypher, params } = query.build({ 45 | labelOperator: "&", 46 | }); 47 | 48 | console.log("Cypher"); 49 | console.log(cypher); 50 | console.log("----"); 51 | console.log("Params", params); 52 | -------------------------------------------------------------------------------- /examples/procedures/custom-procedures.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import Cypher from "../../dist"; 21 | 22 | // CALL myProc(var0) YIELD column AS var1 23 | // RETURN var1 24 | 25 | const responseVar = new Cypher.Variable(); 26 | const customProcedure = new Cypher.Procedure("myProc", [new Cypher.Variable()]).yield(["column", responseVar]); 27 | 28 | const clause = customProcedure.return(responseVar); 29 | 30 | const { cypher, params } = clause.build(); 31 | 32 | console.log("Cypher"); 33 | console.log(cypher); 34 | console.log("----"); 35 | console.log("Params", params); 36 | -------------------------------------------------------------------------------- /examples/procedures/procedures.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import Cypher from "../../dist"; 21 | 22 | // CALL db.labels() yield label as this0 23 | // RETURN this0 24 | 25 | const label = new Cypher.NamedVariable("label"); 26 | 27 | const labelVar = new Cypher.Variable(); 28 | const labelsCall = Cypher.db.labels().yield(["label", labelVar]).return(label); 29 | 30 | const { cypher, params } = labelsCall.build(); 31 | 32 | console.log("Cypher"); 33 | console.log(cypher); 34 | console.log("----"); 35 | console.log("Params", params); 36 | -------------------------------------------------------------------------------- /examples/raw-cypher/raw-cypher-complex.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import Cypher from "../../dist"; 21 | 22 | // MATCH (this0:`Movie`) 23 | // WHERE this0.prop = $myParam 24 | // RETURN this0 25 | 26 | const movie = new Cypher.Node(); 27 | const match = new Cypher.Match(new Cypher.Pattern(movie, { labels: ["Movie"] })) 28 | .where( 29 | new Cypher.Raw((env) => { 30 | const movieStr = env.compile(movie); 31 | 32 | const cypher = `${movieStr}.prop = $myParam`; 33 | const params = { 34 | myParam: "Hello World", 35 | }; 36 | 37 | return [cypher, params]; 38 | }) 39 | ) 40 | .return(movie); 41 | 42 | const { cypher, params } = match.build(); 43 | 44 | console.log("Cypher"); 45 | console.log(cypher); 46 | console.log("----"); 47 | console.log("Params", params); 48 | -------------------------------------------------------------------------------- /examples/raw-cypher/raw-cypher-simple.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import Cypher from "../../dist"; 21 | 22 | // RETURN 10 as myVal 23 | 24 | const customReturn = new Cypher.Raw(`10 as myVal`); 25 | 26 | const returnClause = new Cypher.Return(customReturn); 27 | 28 | const { cypher, params } = returnClause.build(); 29 | 30 | console.log("Cypher"); 31 | console.log(cypher); 32 | console.log("----"); 33 | console.log("Params", params); 34 | -------------------------------------------------------------------------------- /examples/where/complex-where-match.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import Cypher from "../../dist"; 21 | 22 | // MATCH (var0:Movie)-[:ACTED_IN]->(var1:Person) 23 | // WHERE (var1.name = $param0 AND (var0.year = $param1 OR var0.year = $param2)) 24 | // RETURN var0.title 25 | 26 | const movieNode = new Cypher.Variable(); 27 | const personNode = new Cypher.Variable(); 28 | 29 | const actedInRelationship = new Cypher.Pattern(movieNode, { labels: ["Movie"] }) 30 | .related({ type: "ACTED_IN" }) 31 | .to(personNode, { labels: ["Person"] }); 32 | 33 | const matchQuery = new Cypher.Match(actedInRelationship) 34 | .where( 35 | Cypher.and( 36 | Cypher.eq(personNode.property("name"), new Cypher.Param("Keanu Reeves")), 37 | Cypher.or( 38 | Cypher.eq(movieNode.property("year"), new Cypher.Param(1999)), 39 | Cypher.eq(movieNode.property("year"), new Cypher.Param(2000)) 40 | ) 41 | ) 42 | ) 43 | .return(movieNode.property("title")); 44 | 45 | const { cypher, params } = matchQuery.build(); 46 | 47 | console.log("Cypher"); 48 | console.log(cypher); 49 | console.log("----"); 50 | console.log("Params", params); 51 | -------------------------------------------------------------------------------- /examples/where/has-label.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import Cypher from "../../dist"; 21 | 22 | // MATCH (this0) 23 | // WHERE (this0:Film OR this0:Film) 24 | // RETURN this0 25 | 26 | const movieNode = new Cypher.Node(); 27 | 28 | const matchQuery = new Cypher.Match(new Cypher.Pattern(movieNode)) 29 | .where(Cypher.or(movieNode.hasLabel("Movie"), movieNode.hasLabel("Film"))) 30 | .return(movieNode); 31 | 32 | const { cypher, params } = matchQuery.build(); 33 | 34 | console.log("Cypher"); 35 | console.log(cypher); 36 | console.log("----"); 37 | console.log("Params", params); 38 | -------------------------------------------------------------------------------- /examples/where/has-type.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import Cypher from "../../dist"; 21 | 22 | // MATCH (:Movie)-[this0]->(this1:Person) 23 | // WHERE (this0:ACTED_IN OR this0:DIRECTED) 24 | // RETURN this1 25 | 26 | const personNode = new Cypher.Node(); 27 | const actedIn = new Cypher.Relationship(); 28 | 29 | const actedInPattern = new Cypher.Pattern({ labels: ["Movie"] }) 30 | .related(actedIn) 31 | .to(personNode, { labels: ["Person"] }); 32 | 33 | const matchQuery = new Cypher.Match(actedInPattern) 34 | .where(Cypher.or(actedIn.hasType("ACTED_IN"), actedIn.hasType("DIRECTED"))) 35 | .return(personNode); 36 | 37 | const { cypher, params } = matchQuery.build(); 38 | 39 | console.log("Cypher"); 40 | console.log(cypher); 41 | console.log("----"); 42 | console.log("Params", params); 43 | -------------------------------------------------------------------------------- /global.d.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import "jest-extended"; 21 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | displayName: "@neo4j/cypher-builder", 3 | setupFilesAfterEnv: ["jest-extended/all"], 4 | roots: ["/src/", "/tests/"], 5 | coverageDirectory: "/coverage/", 6 | prettierPath: null, 7 | snapshotFormat: { 8 | escapeString: true, 9 | }, 10 | transform: { 11 | "^.+\\.ts$": [ 12 | "ts-jest", 13 | { 14 | tsconfig: "/tsconfig.json", 15 | }, 16 | ], 17 | }, 18 | }; 19 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@neo4j/cypher-builder", 3 | "version": "2.7.0", 4 | "description": "A programmatic API for building Cypher queries for Neo4j", 5 | "exports": "./dist/index.js", 6 | "main": "./dist/index.js", 7 | "types": "./dist/index.d.ts", 8 | "files": [ 9 | "dist/**/*.ts", 10 | "dist/**/*.ts.map", 11 | "dist/**/*.js", 12 | "dist/**/*.js.map" 13 | ], 14 | "engines": { 15 | "node": ">=16.0.0" 16 | }, 17 | "scripts": { 18 | "test": "jest", 19 | "build": "tsc --build tsconfig.production.json", 20 | "docs": "npm run antora-docs && npm run docs-ref", 21 | "antora-docs": "npm run build --prefix ./docs", 22 | "docs-ref": "typedoc src/Cypher.ts", 23 | "lint": "eslint .", 24 | "changeset": "changeset", 25 | "release": "npm run build && changeset publish", 26 | "prettier": "prettier . --check" 27 | }, 28 | "repository": { 29 | "type": "git", 30 | "url": "git+https://github.com/neo4j/cypher-builder.git" 31 | }, 32 | "keywords": [ 33 | "neo4j", 34 | "cypher", 35 | "query", 36 | "builder" 37 | ], 38 | "author": "Neo4j Inc.", 39 | "license": "Apache-2.0", 40 | "bugs": { 41 | "url": "https://github.com/neo4j/cypher-builder/issues" 42 | }, 43 | "homepage": "https://neo4j.github.io/cypher-builder/", 44 | "devDependencies": { 45 | "@changesets/changelog-github": "^0.5.1", 46 | "@changesets/cli": "^2.27.10", 47 | "@eslint/js": "^9.15.0", 48 | "@tsconfig/node16": "^16.1.3", 49 | "@types/jest": "^29.5.14", 50 | "@types/node": "^22.10.0", 51 | "@typescript-eslint/eslint-plugin": "^8.16.0", 52 | "@typescript-eslint/parser": "^8.16.0", 53 | "eslint": "^9.15.0", 54 | "eslint-config-prettier": "^10.0.0", 55 | "eslint-plugin-tsdoc": "^0.4.0", 56 | "globals": "^16.0.0", 57 | "jest": "^29.7.0", 58 | "jest-extended": "^6.0.0", 59 | "prettier": "^3.4.1", 60 | "ts-jest": "^29.2.5", 61 | "typedoc": "^0.28.5", 62 | "typescript": "^5.6.3" 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["config:base"], 3 | "baseBranches": ["main"], 4 | "rebaseWhen": "auto", 5 | "automerge": true, 6 | "major": { 7 | "automerge": false 8 | }, 9 | "timezone": "Europe/London", 10 | "schedule": ["after 10pm every weekday", "before 5am every weekday", "every weekend"], 11 | "ignorePaths": [ 12 | "**/node_modules/**", 13 | "**/bower_components/**", 14 | "**/vendor/**", 15 | "**/__tests__/**", 16 | "**/test/**", 17 | "**/tests/**", 18 | "**/__fixtures__/**" 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /sonar-project.properties: -------------------------------------------------------------------------------- 1 | sonar.projectKey=neo4j_cypher-builder 2 | sonar.organization=neo4j-organization 3 | 4 | sonar.javascript.lcov.reportPaths=coverage/lcov.info 5 | 6 | sonar.sources = src/ 7 | sonar.tests = tests/ 8 | 9 | sonar.coverage.exclusions=*/**/*.test.ts 10 | sonar.cpd.exclusions=*/**/*.test.ts 11 | 12 | sonar.typescript.tsconfigPaths = tsconfig.json 13 | -------------------------------------------------------------------------------- /src/CypherASTNode.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import type { CypherEnvironment } from "./Environment"; 21 | import type { CypherCompilable } from "./types"; 22 | 23 | /** Abstract class representing a Cypher Statement in the AST 24 | * @internal 25 | */ 26 | export abstract class CypherASTNode implements CypherCompilable { 27 | protected parent?: CypherASTNode; 28 | 29 | /** @internal */ 30 | constructor(parent?: CypherASTNode) { 31 | this.parent = parent; 32 | } 33 | 34 | /** @internal */ 35 | public getRoot(): CypherASTNode { 36 | if (this.parent) { 37 | return this.parent.getRoot(); 38 | } 39 | return this; 40 | } 41 | 42 | /** Concrete tree traversal pattern to generate the Cypher on nested nodes 43 | * @internal 44 | */ 45 | public abstract getCypher(env: CypherEnvironment): string; 46 | 47 | /** Sets the parent-child relationship for build traversal */ 48 | protected addChildren(...nodes: CypherCompilable[]): void { 49 | for (const node of nodes) { 50 | if (node instanceof CypherASTNode) { 51 | node.setParent(this); 52 | } 53 | } 54 | } 55 | 56 | protected setParent(node: CypherASTNode): void { 57 | this.parent = node; 58 | } 59 | 60 | protected get isRoot(): boolean { 61 | return this.parent === undefined; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/clauses/Finish.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import Cypher from ".."; 21 | 22 | describe("CypherBuilder Finish", () => { 23 | test("Finish Clause", () => { 24 | const finishQuery = new Cypher.Finish(); 25 | 26 | const queryResult = finishQuery.build(); 27 | expect(queryResult.cypher).toMatchInlineSnapshot(`"FINISH"`); 28 | expect(queryResult.params).toMatchInlineSnapshot(`{}`); 29 | }); 30 | 31 | test("Create.withFinish", () => { 32 | const node = new Cypher.Node(); 33 | 34 | const createQuery = new Cypher.Create(new Cypher.Pattern(new Cypher.Node())) 35 | .set([node.property("test"), new Cypher.Param("Hello World")]) 36 | .finish(); 37 | 38 | const queryResult = createQuery.build(); 39 | expect(queryResult.cypher).toMatchInlineSnapshot(` 40 | "CREATE (this0) 41 | SET 42 | this1.test = $param0 43 | FINISH" 44 | `); 45 | expect(queryResult.params).toMatchInlineSnapshot(` 46 | { 47 | "param0": "Hello World", 48 | } 49 | `); 50 | }); 51 | 52 | test("Match.withFinish", () => { 53 | const createQuery = new Cypher.Match(new Cypher.Pattern(new Cypher.Node())).finish(); 54 | 55 | const queryResult = createQuery.build(); 56 | expect(queryResult.cypher).toMatchInlineSnapshot(` 57 | "MATCH (this0) 58 | FINISH" 59 | `); 60 | expect(queryResult.params).toMatchInlineSnapshot(`{}`); 61 | }); 62 | }); 63 | -------------------------------------------------------------------------------- /src/clauses/Finish.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import { Clause } from "./Clause"; 21 | 22 | /** 23 | * @see {@link https://neo4j.com/docs/cypher-manual/current/clauses/finish/ | Cypher Documentation} 24 | * @group Clauses 25 | * @since Neo4j 5.19 26 | */ 27 | export class Finish extends Clause { 28 | /** @internal */ 29 | public getCypher(): string { 30 | return "FINISH"; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/clauses/LoadCSV.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import Cypher from ".."; 21 | 22 | describe("LoadCSV", () => { 23 | test("Simple LoadCSV", () => { 24 | const row = new Cypher.Variable(); 25 | const loadClause = new Cypher.LoadCSV("https://data.neo4j.com/bands/artists.csv", row).return(row); 26 | 27 | const queryResult = loadClause.build(); 28 | expect(queryResult.cypher).toMatchInlineSnapshot(` 29 | "LOAD CSV FROM \\"https://data.neo4j.com/bands/artists.csv\\" AS var0 30 | RETURN var0" 31 | `); 32 | 33 | expect(queryResult.params).toMatchInlineSnapshot(`{}`); 34 | }); 35 | 36 | test("LoadCSV with headers", () => { 37 | const row = new Cypher.Variable(); 38 | const node = new Cypher.Node(); 39 | const loadClause = new Cypher.LoadCSV("https://data.neo4j.com/bands/artists.csv", row) 40 | .withHeaders() 41 | .merge( 42 | new Cypher.Pattern(node, { 43 | properties: { 44 | name: row.property("Name"), 45 | }, 46 | }) 47 | ) 48 | .return(row); 49 | 50 | const queryResult = loadClause.build(); 51 | expect(queryResult.cypher).toMatchInlineSnapshot(` 52 | "LOAD CSV WITH HEADERS FROM \\"https://data.neo4j.com/bands/artists.csv\\" AS var0 53 | MERGE (this1 { name: var0.Name }) 54 | RETURN var0" 55 | `); 56 | 57 | expect(queryResult.params).toMatchInlineSnapshot(`{}`); 58 | }); 59 | }); 60 | -------------------------------------------------------------------------------- /src/clauses/Use.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import type { CypherASTNode } from "../CypherASTNode"; 21 | import type { CypherEnvironment } from "../Environment"; 22 | import { Clause } from "./Clause"; 23 | 24 | /** 25 | * @see {@link https://neo4j.com/docs/cypher-manual/5/clauses/use/ | Cypher Documentation} 26 | * @group Clauses 27 | */ 28 | export class Use extends Clause { 29 | private readonly graph: string; 30 | private readonly subClause: CypherASTNode; 31 | 32 | constructor(graph: string, subClause: Clause) { 33 | super(); 34 | this.subClause = subClause.getRoot(); 35 | this.graph = graph; 36 | this.addChildren(this.subClause); 37 | } 38 | 39 | /** @internal */ 40 | public getCypher(env: CypherEnvironment): string { 41 | const subClauseStr = this.subClause.getCypher(env); 42 | return `USE ${this.graph}\n${subClauseStr}`; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/clauses/mixins/Mixin.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import { Clause } from "../../clauses/Clause"; 21 | import { CypherASTNode } from "../../CypherASTNode"; 22 | 23 | /** 24 | * Superclass of all mixins in CypherBuilder 25 | */ 26 | export abstract class Mixin extends CypherASTNode {} 27 | 28 | export abstract class MixinClause extends Clause {} 29 | -------------------------------------------------------------------------------- /src/clauses/mixins/clauses/WithCall.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import type { Clause, Variable } from "../../.."; 21 | import { Call, OptionalCall } from "../../.."; 22 | import { MixinClause } from "../Mixin"; 23 | 24 | export abstract class WithCall extends MixinClause { 25 | /** Add a {@link Call} clause 26 | * @see {@link https://neo4j.com/docs/cypher-manual/current/subqueries/call-subquery/ | Cypher Documentation} 27 | */ 28 | public call(subquery: Clause, variableScope?: Variable[] | "*"): Call { 29 | const callClause = new Call(subquery, variableScope); 30 | this.addNextClause(callClause); 31 | 32 | return callClause; 33 | } 34 | 35 | /** Add a {@link OptionalCall} clause 36 | */ 37 | public optionalCall(subquery: Clause, variableScope?: Variable[] | "*"): Call { 38 | const callClause = new OptionalCall(subquery, variableScope); 39 | this.addNextClause(callClause); 40 | 41 | return callClause; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/clauses/mixins/clauses/WithCallProcedure.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import type { CypherProcedure, VoidCypherProcedure } from "../../../procedures/CypherProcedure"; 21 | import { MixinClause } from "../Mixin"; 22 | 23 | export abstract class WithCallProcedure extends MixinClause { 24 | /** Add a call {@link Procedure} clause 25 | * @see {@link https://neo4j.com/docs/cypher-manual/current/clauses/call/ | Cypher Documentation} 26 | */ 27 | public callProcedure(procedure: T): T { 28 | this.addNextClause(procedure); 29 | return procedure; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/clauses/mixins/clauses/WithCreate.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import type { Pattern } from "../../.."; 21 | import { Create } from "../../.."; 22 | import { MixinClause } from "../Mixin"; 23 | 24 | export abstract class WithCreate extends MixinClause { 25 | /** Add a {@link Create} clause 26 | * @see {@link https://neo4j.com/docs/cypher-manual/current/clauses/create/ | Cypher Documentation} 27 | */ 28 | 29 | public create(clauseOrPattern: Create | Pattern): Create { 30 | if (clauseOrPattern instanceof Create) { 31 | this.addNextClause(clauseOrPattern); 32 | return clauseOrPattern; 33 | } 34 | 35 | const matchClause = new Create(clauseOrPattern); 36 | this.addNextClause(matchClause); 37 | 38 | return matchClause; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/clauses/mixins/clauses/WithFinish.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import { Finish } from "../../.."; 21 | import { MixinClause } from "../Mixin"; 22 | 23 | export abstract class WithFinish extends MixinClause { 24 | /** Append a {@link Finish} clause 25 | * @see {@link https://neo4j.com/docs/cypher-manual/current/clauses/finish/ | Cypher Documentation} 26 | */ 27 | public finish(): Finish { 28 | const finishClause = new Finish(); 29 | this.addNextClause(finishClause); 30 | 31 | return finishClause; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/clauses/mixins/clauses/WithForeach.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import type { Foreach } from "../../.."; 21 | import Cypher from "../../.."; 22 | import { MixinClause } from "../Mixin"; 23 | 24 | export abstract class WithForeach extends MixinClause { 25 | /** Add a {@link Foreach} clause 26 | * @see {@link https://neo4j.com/docs/cypher-manual/current/clauses/foreach/ | Cypher Documentation} 27 | */ 28 | 29 | public foreach(variable: Cypher.Variable): Foreach { 30 | const foreach = new Cypher.Foreach(variable); 31 | this.addNextClause(foreach); 32 | return foreach; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/clauses/mixins/clauses/WithMatch.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import { Match, OptionalMatch } from "../../.."; 21 | import type { MatchClausePattern } from "../../Match"; 22 | import { MixinClause } from "../Mixin"; 23 | 24 | export abstract class WithMatch extends MixinClause { 25 | /** Add a {@link Match} clause 26 | * @see {@link https://neo4j.com/docs/cypher-manual/current/clauses/match/ | Cypher Documentation} 27 | */ 28 | 29 | public match(clauseOrPattern: Match | MatchClausePattern): Match { 30 | if (clauseOrPattern instanceof Match) { 31 | this.addNextClause(clauseOrPattern); 32 | return clauseOrPattern; 33 | } 34 | 35 | const matchClause = new Match(clauseOrPattern); 36 | this.addNextClause(matchClause); 37 | 38 | return matchClause; 39 | } 40 | 41 | /** Add an {@link OptionalMatch} clause 42 | * @see {@link https://neo4j.com/docs/cypher-manual/current/clauses/optional-match/ | Cypher Documentation} 43 | */ 44 | 45 | public optionalMatch(clauseOrPattern: OptionalMatch | MatchClausePattern): OptionalMatch { 46 | if (clauseOrPattern instanceof OptionalMatch) { 47 | this.addNextClause(clauseOrPattern); 48 | return clauseOrPattern; 49 | } 50 | const matchClause = new OptionalMatch(clauseOrPattern); 51 | this.addNextClause(matchClause); 52 | 53 | return matchClause; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/clauses/mixins/clauses/WithMerge.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import type { Pattern } from "../../.."; 21 | import { Merge } from "../../.."; 22 | import { MixinClause } from "../Mixin"; 23 | 24 | export abstract class WithMerge extends MixinClause { 25 | /** Add a {@link Merge} clause 26 | * @see {@link https://neo4j.com/docs/cypher-manual/current/clauses/merge/ | Cypher Documentation} 27 | */ 28 | 29 | public merge(clauseOrPattern: Merge | Pattern): Merge { 30 | if (clauseOrPattern instanceof Merge) { 31 | this.addNextClause(clauseOrPattern); 32 | return clauseOrPattern; 33 | } 34 | 35 | const matchClause = new Merge(clauseOrPattern); 36 | this.addNextClause(matchClause); 37 | 38 | return matchClause; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/clauses/mixins/clauses/WithReturn.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import { Return } from "../../Return"; 21 | import type { ProjectionColumn } from "../../sub-clauses/Projection"; 22 | import { MixinClause } from "../Mixin"; 23 | 24 | export abstract class WithReturn extends MixinClause { 25 | /** Append a {@link Return} clause 26 | * @see {@link https://neo4j.com/docs/cypher-manual/current/clauses/return/ | Cypher Documentation} 27 | */ 28 | public return(clause: Return): Return; 29 | public return(...columns: Array<"*" | ProjectionColumn>): Return; 30 | public return(clauseOrColumn: Return | "*" | ProjectionColumn, ...columns: Array<"*" | ProjectionColumn>): Return { 31 | const returnClause = this.getReturnClause(clauseOrColumn, columns); 32 | this.addNextClause(returnClause); 33 | return returnClause; 34 | } 35 | 36 | private getReturnClause( 37 | clauseOrColumn: Return | "*" | ProjectionColumn, 38 | columns: Array<"*" | ProjectionColumn> 39 | ): Return { 40 | if (clauseOrColumn instanceof Return) { 41 | return clauseOrColumn; 42 | } else { 43 | return new Return(clauseOrColumn, ...columns); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/clauses/mixins/clauses/WithUnwind.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import type { UnwindProjectionColumn } from "../../Unwind"; 21 | import { Unwind } from "../../Unwind"; 22 | import { MixinClause } from "../Mixin"; 23 | 24 | export abstract class WithUnwind extends MixinClause { 25 | /** Append an {@link Unwind} clause. 26 | * @see {@link https://neo4j.com/docs/cypher-manual/current/clauses/unwind/ | Cypher Documentation} 27 | */ 28 | public unwind(clause: Unwind): Unwind; 29 | public unwind(projection: UnwindProjectionColumn): Unwind; 30 | public unwind(clauseOrColumn: Unwind | UnwindProjectionColumn): Unwind { 31 | const unwindClause = this.getUnwindClause(clauseOrColumn); 32 | this.addNextClause(unwindClause); 33 | return unwindClause; 34 | } 35 | 36 | private getUnwindClause(clauseOrColumn: Unwind | UnwindProjectionColumn): Unwind { 37 | if (clauseOrColumn instanceof Unwind) { 38 | return clauseOrColumn; 39 | } else { 40 | return new Unwind(clauseOrColumn); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/clauses/mixins/clauses/WithWith.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import { With } from "../../.."; 21 | import type { WithProjection } from "../../With"; 22 | import { MixinClause } from "../Mixin"; 23 | 24 | export abstract class WithWith extends MixinClause { 25 | /** Add a {@link With} clause 26 | * @see {@link https://neo4j.com/docs/cypher-manual/current/clauses/with/ | Cypher Documentation} 27 | */ 28 | public with(clause: With): With; 29 | public with(...columns: Array<"*" | WithProjection>): With; 30 | public with(clauseOrColumn: With | "*" | WithProjection, ...columns: Array<"*" | WithProjection>): With { 31 | const withClause = this.getWithClause(clauseOrColumn, columns); 32 | this.addNextClause(withClause); 33 | return withClause; 34 | } 35 | 36 | private getWithClause(clauseOrColumn: With | "*" | WithProjection, columns: Array<"*" | WithProjection>): With { 37 | if (clauseOrColumn instanceof With) { 38 | return clauseOrColumn; 39 | } else { 40 | return new With(clauseOrColumn, ...columns); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/clauses/sub-clauses/Delete.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import { CypherASTNode } from "../../CypherASTNode"; 21 | import type { CypherEnvironment } from "../../Environment"; 22 | import type { NodeRef } from "../../references/NodeRef"; 23 | import type { RelationshipRef } from "../../references/RelationshipRef"; 24 | import type { Variable } from "../../references/Variable"; 25 | 26 | /** @group Clauses */ 27 | export type DeleteInput = Array; 28 | 29 | type DetachKeyword = "DETACH" | "NODETACH"; 30 | 31 | export class DeleteClause extends CypherASTNode { 32 | private readonly deleteInput: DeleteInput; 33 | private detachKeyword: DetachKeyword | undefined; 34 | 35 | constructor(parent: CypherASTNode | undefined, deleteInput: DeleteInput) { 36 | super(parent); 37 | this.deleteInput = deleteInput; 38 | } 39 | 40 | public detach(): void { 41 | this.detachKeyword = "DETACH"; 42 | } 43 | 44 | public noDetach(): void { 45 | this.detachKeyword = "NODETACH"; 46 | } 47 | 48 | /** @internal */ 49 | public getCypher(env: CypherEnvironment): string { 50 | const itemsToDelete = this.deleteInput.map((e) => e.getCypher(env)); 51 | const detachStr = this.detachKeyword ? `${this.detachKeyword} ` : ""; 52 | return `${detachStr}DELETE ${itemsToDelete.join(",")}`; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/clauses/sub-clauses/ImportWith.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import { CypherASTNode } from "../../CypherASTNode"; 21 | import type { CypherEnvironment } from "../../Environment"; 22 | import type { Param } from "../../references/Param"; 23 | import type { PropertyRef } from "../../references/PropertyRef"; 24 | import type { Variable } from "../../references/Variable"; 25 | import type { Call } from "../Call"; 26 | 27 | export type SetParam = [PropertyRef, Param]; 28 | 29 | /** Represents a WITH statement to import variables into a CALL subquery */ 30 | export class ImportWith extends CypherASTNode { 31 | private readonly params: Variable[]; 32 | private hasStar = false; 33 | 34 | constructor(parent: Call, params: Array<"*" | Variable>) { 35 | super(parent); 36 | this.params = this.filterParams(params); 37 | } 38 | 39 | /** @internal */ 40 | public getCypher(env: CypherEnvironment): string { 41 | let paramsStr = this.params.map((v) => v.getCypher(env)); 42 | if (this.hasStar) { 43 | paramsStr = ["*", ...paramsStr]; 44 | } 45 | 46 | return `WITH ${paramsStr.join(", ")}`; 47 | } 48 | 49 | private filterParams(params: Array<"*" | Variable>): Variable[] { 50 | return params.filter((p: "*" | Variable): p is Variable => { 51 | if (p === "*") { 52 | this.hasStar = true; 53 | return false; 54 | } 55 | return true; 56 | }); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/clauses/sub-clauses/OnCreate.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import type { CypherEnvironment } from "../../Environment"; 21 | import type { SetParam } from "./Set"; 22 | import { SetClause } from "./Set"; 23 | 24 | export type OnCreateParam = SetParam; 25 | 26 | export class OnCreate extends SetClause { 27 | /** @internal */ 28 | public getCypher(env: CypherEnvironment): string { 29 | if (this.params.length === 0) return ""; 30 | const setCypher = super.getCypher(env); 31 | return `ON CREATE ${setCypher}`; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/clauses/sub-clauses/OnMatch.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import type { CypherEnvironment } from "../../Environment"; 21 | import type { SetParam } from "./Set"; 22 | import { SetClause } from "./Set"; 23 | 24 | export type OnMatchParam = SetParam; 25 | 26 | export class OnMatch extends SetClause { 27 | /** @internal */ 28 | public getCypher(env: CypherEnvironment): string { 29 | if (this.params.length === 0) return ""; 30 | const setCypher = super.getCypher(env); 31 | return `ON MATCH ${setCypher}`; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/clauses/sub-clauses/Remove.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import { CypherASTNode } from "../../CypherASTNode"; 21 | import type { CypherEnvironment } from "../../Environment"; 22 | import type { Label } from "../../references/Label"; 23 | import type { PropertyRef } from "../../references/PropertyRef"; 24 | 25 | export class RemoveClause extends CypherASTNode { 26 | private readonly removeInput: Array; 27 | 28 | constructor(parent: CypherASTNode | undefined, removeInput: Array) { 29 | super(parent); 30 | this.removeInput = removeInput; 31 | } 32 | 33 | public addParams(...params: Array): void { 34 | this.removeInput.push(...params); 35 | } 36 | 37 | /** @internal */ 38 | public getCypher(env: CypherEnvironment): string { 39 | const propertiesToDelete = this.removeInput.map((e) => e.getCypher(env)); 40 | return `REMOVE ${propertiesToDelete.join(", ")}`; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/clauses/sub-clauses/Where.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import { CypherASTNode } from "../../CypherASTNode"; 21 | import type { CypherEnvironment } from "../../Environment"; 22 | import { and } from "../../expressions/operations/boolean"; 23 | import type { Predicate } from "../../types"; 24 | 25 | export class Where extends CypherASTNode { 26 | private wherePredicate: Predicate; 27 | 28 | constructor(parent: CypherASTNode | undefined, whereInput: Predicate) { 29 | super(parent); 30 | this.wherePredicate = whereInput; 31 | this.addChildren(this.wherePredicate); 32 | } 33 | 34 | public and(op: Predicate): void { 35 | this.wherePredicate = and(this.wherePredicate, op); 36 | this.addChildren(this.wherePredicate); 37 | } 38 | 39 | /** @internal */ 40 | public getCypher(env: CypherEnvironment): string { 41 | const opStr = this.wherePredicate.getCypher(env); 42 | if (!opStr) return ""; 43 | return `WHERE ${opStr}`; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/expressions/functions/CypherFunctions.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import { TestClause } from "../../utils/TestClause"; 21 | import Cypher from "../.."; 22 | 23 | describe("Cypher Functions", () => { 24 | test("custom function", () => { 25 | const myFunction = new Cypher.Function("myFunction", [new Cypher.Literal("test"), new Cypher.Param("test2")]); 26 | const queryResult = new TestClause(myFunction).build(); 27 | 28 | expect(queryResult.cypher).toMatchInlineSnapshot(`"myFunction(\\"test\\", $param0)"`); 29 | 30 | expect(queryResult.params).toMatchInlineSnapshot(` 31 | { 32 | "param0": "test2", 33 | } 34 | `); 35 | }); 36 | }); 37 | -------------------------------------------------------------------------------- /src/expressions/functions/graph.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import { TestClause } from "../../utils/TestClause"; 21 | import Cypher from "../.."; 22 | 23 | describe("Graph Functions", () => { 24 | test("graph.names()", () => { 25 | const labelsFn = Cypher.graph.names(); 26 | 27 | const queryResult = new TestClause(labelsFn).build(); 28 | expect(queryResult.cypher).toMatchInlineSnapshot(`"graph.names()"`); 29 | }); 30 | 31 | test("graph.propertiesByName()", () => { 32 | const labelsFn = Cypher.graph.propertiesByName(new Cypher.Variable()); 33 | 34 | const queryResult = new TestClause(labelsFn).build(); 35 | expect(queryResult.cypher).toMatchInlineSnapshot(`"graph.propertiesByName(var0)"`); 36 | }); 37 | 38 | test("graph.byName()", () => { 39 | const labelsFn = Cypher.graph.byName(new Cypher.Variable()); 40 | 41 | const queryResult = new TestClause(labelsFn).build(); 42 | expect(queryResult.cypher).toMatchInlineSnapshot(`"graph.propertiesByName(var0)"`); 43 | }); 44 | }); 45 | -------------------------------------------------------------------------------- /src/expressions/functions/graph.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import type { Expr } from "../../types"; 21 | import { CypherFunction } from "./CypherFunctions"; 22 | 23 | /** 24 | * @see {@link https://neo4j.com/docs/cypher-manual/current/functions/graph/#functions-graph-names | Cypher Documentation} 25 | * @group Functions 26 | */ 27 | export function names(): CypherFunction { 28 | return new CypherFunction("graph.names"); 29 | } 30 | /** 31 | * @see {@link https://neo4j.com/docs/cypher-manual/current/functions/graph/#functions-graph-propertiesByName | Cypher Documentation} 32 | * @group Functions 33 | */ 34 | export function propertiesByName(name: Expr): CypherFunction { 35 | return new CypherFunction("graph.propertiesByName", [name]); 36 | } 37 | /** 38 | * @see {@link https://neo4j.com/docs/cypher-manual/current/functions/graph/#functions-graph-byname | Cypher Documentation} 39 | * @group Functions 40 | */ 41 | export function byName(graphName: Expr): CypherFunction { 42 | return new CypherFunction("graph.propertiesByName", [graphName]); 43 | } 44 | -------------------------------------------------------------------------------- /src/expressions/functions/load-csv.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import Cypher from "../.."; 21 | 22 | describe("Load CSV Functions", () => { 23 | test.each(["file", "linenumber"] as const)("%s()", (value) => { 24 | const func = Cypher[value](); 25 | 26 | const { cypher } = new Cypher.Return(func).build(); 27 | expect(cypher).toBe(`RETURN ${value}()`); 28 | }); 29 | }); 30 | -------------------------------------------------------------------------------- /src/expressions/functions/load-csv.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import { CypherFunction } from "./CypherFunctions"; 21 | 22 | /** 23 | * @see {@link https://neo4j.com/docs/cypher-manual/current/clauses/load-csv/#_access_line_numbers_with_linenumber | Cypher Documentation} 24 | * @group Functions 25 | */ 26 | export function linenumber(): CypherFunction { 27 | return new CypherFunction("linenumber"); 28 | } 29 | 30 | /** 31 | * @see {@link https://neo4j.com/docs/cypher-manual/current/clauses/load-csv/#_access_the_csv_file_path_with_file | Cypher Documentation} 32 | * @group Functions 33 | */ 34 | export function file(): CypherFunction { 35 | return new CypherFunction("file"); 36 | } 37 | -------------------------------------------------------------------------------- /src/expressions/functions/path.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import Cypher from "../.."; 21 | import { TestClause } from "../../utils/TestClause"; 22 | 23 | describe("Path Functions", () => { 24 | test("nodes", () => { 25 | const nodesFn = Cypher.nodes(new Cypher.PathVariable()); 26 | 27 | const queryResult = new TestClause(nodesFn).build(); 28 | 29 | expect(queryResult.cypher).toMatchInlineSnapshot(`"nodes(p0)"`); 30 | expect(queryResult.params).toMatchInlineSnapshot(`{}`); 31 | }); 32 | 33 | test("relationships", () => { 34 | const relationshipsFn = Cypher.relationships(new Cypher.PathVariable()); 35 | 36 | const queryResult = new TestClause(relationshipsFn).build(); 37 | 38 | expect(queryResult.cypher).toMatchInlineSnapshot(`"relationships(p0)"`); 39 | expect(queryResult.params).toMatchInlineSnapshot(`{}`); 40 | }); 41 | 42 | test("NamedPath", () => { 43 | const nodesFn = Cypher.nodes(new Cypher.NamedPathVariable("my_path")); 44 | 45 | const queryResult = new TestClause(nodesFn).build(); 46 | 47 | expect(queryResult.cypher).toMatchInlineSnapshot(`"nodes(my_path)"`); 48 | expect(queryResult.params).toMatchInlineSnapshot(`{}`); 49 | }); 50 | }); 51 | -------------------------------------------------------------------------------- /src/expressions/functions/path.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import type { PathVariable } from "../../references/Path"; 21 | import { CypherFunction } from "./CypherFunctions"; 22 | 23 | /** 24 | * @see {@link https://neo4j.com/docs/cypher-cheat-sheet/current/#_path_functions | Cypher Documentation} 25 | * @group Functions 26 | * @category Path 27 | */ 28 | export function nodes(path: PathVariable): CypherFunction { 29 | return new CypherFunction("nodes", [path]); 30 | } 31 | 32 | /** 33 | * @see {@link https://neo4j.com/docs/cypher-cheat-sheet/current/#_path_functions | Cypher Documentation} 34 | * @group Functions 35 | * @category Path 36 | */ 37 | export function relationships(path: PathVariable): CypherFunction { 38 | return new CypherFunction("relationships", [path]); 39 | } 40 | -------------------------------------------------------------------------------- /src/expressions/list/ListExpr.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import Cypher from "../.."; 21 | import { TestClause } from "../../utils/TestClause"; 22 | 23 | describe("List", () => { 24 | test("list of Literals", () => { 25 | const cypherList = new Cypher.List([new Cypher.Literal("1"), new Cypher.Literal("2"), new Cypher.Literal("3")]); 26 | 27 | const queryResult = new TestClause(cypherList).build(); 28 | 29 | expect(queryResult.cypher).toMatchInlineSnapshot(`"[\\"1\\", \\"2\\", \\"3\\"]"`); 30 | expect(queryResult.params).toMatchInlineSnapshot(`{}`); 31 | }); 32 | 33 | test("access list index", () => { 34 | const cypherList = new Cypher.List([new Cypher.Literal("1"), new Cypher.Literal("2"), new Cypher.Literal("3")]); 35 | const listIndex = cypherList.index(0); 36 | const queryResult = new TestClause(listIndex).build(); 37 | 38 | expect(queryResult.cypher).toMatchInlineSnapshot(`"[\\"1\\", \\"2\\", \\"3\\"][0]"`); 39 | expect(queryResult.params).toMatchInlineSnapshot(`{}`); 40 | }); 41 | }); 42 | -------------------------------------------------------------------------------- /src/expressions/list/ListExpr.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import type { CypherEnvironment } from "../../Environment"; 21 | import type { CypherCompilable, Expr } from "../../types"; 22 | import { ListIndex } from "./ListIndex"; 23 | 24 | /** Represents a List 25 | * @see {@link https://neo4j.com/docs/cypher-manual/current/syntax/lists/ | Cypher Documentation} 26 | * @group Lists 27 | * @example 28 | * ```ts 29 | * new Cypher.List([new Cypher.Literal("1"), new Cypher.Literal("2"), new Cypher.Literal("3")]) 30 | * ``` 31 | * Translates to 32 | * ```cypher 33 | * [ "1", "2", "3" ] 34 | * ``` 35 | */ 36 | export class ListExpr implements CypherCompilable { 37 | private readonly value: Expr[]; 38 | 39 | constructor(value: Expr[]) { 40 | this.value = value; 41 | } 42 | 43 | private serializeList(env: CypherEnvironment, obj: Expr[]): string { 44 | const valuesList = obj.map((expr) => { 45 | return expr.getCypher(env); 46 | }); 47 | 48 | const serializedContent = valuesList.join(", "); 49 | return `[${serializedContent}]`; 50 | } 51 | 52 | /** @internal */ 53 | public getCypher(env: CypherEnvironment): string { 54 | return this.serializeList(env, this.value); 55 | } 56 | 57 | /** Access individual elements in the list */ 58 | public index(index: number): ListIndex { 59 | return new ListIndex(this, index); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/expressions/list/ListIndex.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import Cypher from "../.."; 21 | import { TestClause } from "../../utils/TestClause"; 22 | import { ListIndex } from "./ListIndex"; 23 | 24 | describe("ListIndex", () => { 25 | test("get 0", () => { 26 | const list = new Cypher.List([new Cypher.Literal("1"), new Cypher.Literal("2"), new Cypher.Literal("3")]); 27 | const listIndex = new ListIndex(list, 0); 28 | const queryResult = new TestClause(listIndex).build(); 29 | 30 | expect(queryResult.cypher).toMatchInlineSnapshot(`"[\\"1\\", \\"2\\", \\"3\\"][0]"`); 31 | expect(queryResult.params).toMatchInlineSnapshot(`{}`); 32 | }); 33 | }); 34 | -------------------------------------------------------------------------------- /src/expressions/list/ListIndex.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import type { CypherEnvironment } from "../../Environment"; 21 | import type { PropertyRef } from "../../references/PropertyRef"; 22 | import type { Variable } from "../../references/Variable"; 23 | import type { CypherCompilable } from "../../types"; 24 | import type { ListExpr } from "./ListExpr"; 25 | 26 | /** 27 | * @group Lists 28 | */ 29 | export class ListIndex implements CypherCompilable { 30 | private readonly value: Variable | ListExpr | PropertyRef; 31 | private readonly index: number; 32 | 33 | /** 34 | * @internal 35 | */ 36 | constructor(variable: Variable | ListExpr | PropertyRef, index: number) { 37 | this.value = variable; 38 | this.index = index; 39 | } 40 | 41 | /** @internal */ 42 | public getCypher(env: CypherEnvironment): string { 43 | return `${this.value.getCypher(env)}[${this.index}]`; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/expressions/operations/concat.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import { CypherASTNode } from "../../CypherASTNode"; 21 | import type { CypherEnvironment } from "../../Environment"; 22 | import type { Expr } from "../../types"; 23 | 24 | const ConcatOperator = "||"; 25 | 26 | /** 27 | * The concatenation operator (`||`) generated by {@link concat} 28 | * @group Operators 29 | * @category String 30 | */ 31 | export class ConcatOp extends CypherASTNode { 32 | private readonly exprs: Expr[]; 33 | 34 | /** @internal */ 35 | constructor(exprs: Expr[]) { 36 | super(); 37 | this.exprs = exprs; 38 | } 39 | 40 | /** 41 | * @internal 42 | */ 43 | public getCypher(env: CypherEnvironment): string { 44 | const exprs = this.exprs.map((e) => e.getCypher(env)); 45 | 46 | const operatorStr = ` ${ConcatOperator} `; 47 | return `(${exprs.join(operatorStr)})`; 48 | } 49 | } 50 | 51 | /** Concat (||) operator. This operator may be used for concatenating strings. For concatenating Cypher builder clauses use `utils.concat` 52 | * @see {@link https://neo4j.com/docs/cypher-manual/current/syntax/operators/#syntax-concatenating-two-strings-doublebar | Cypher Documentation} 53 | * @group Operators 54 | * @category String 55 | * @since Neo4j 5.19 56 | */ 57 | export function concat(leftExpr: Expr, rightExpr: Expr): ConcatOp; 58 | export function concat(...exprs: Expr[]): ConcatOp; 59 | export function concat(...exprs: Expr[]): ConcatOp { 60 | return new ConcatOp(exprs); 61 | } 62 | -------------------------------------------------------------------------------- /src/expressions/subquery/Collect.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import type { CypherEnvironment } from "../../Environment"; 21 | import { padBlock } from "../../utils/pad-block"; 22 | import { Subquery } from "./Subquery"; 23 | 24 | /** 25 | * @see {@link https://neo4j.com/docs/cypher-manual/current/subqueries/collect/ | Cypher Documentation} 26 | * @group Subqueries 27 | */ 28 | export class Collect extends Subquery { 29 | /** 30 | * @internal 31 | */ 32 | public getCypher(env: CypherEnvironment): string { 33 | const subQueryStr = this.subquery.getCypher(env); 34 | const paddedSubQuery = padBlock(subQueryStr); 35 | return `COLLECT {\n${paddedSubQuery}\n}`; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/expressions/subquery/Count.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import Cypher from "../.."; 21 | 22 | describe("Count Subquery", () => { 23 | test("Count predicate with subclause", () => { 24 | const subquery = new Cypher.Match(new Cypher.Pattern(new Cypher.Node(), { labels: ["Movie"] })).return("*"); 25 | 26 | const countExpr = new Cypher.Count(subquery); 27 | const match = new Cypher.Match(new Cypher.Pattern(new Cypher.Node())) 28 | .where(Cypher.gt(countExpr, new Cypher.Literal(10))) 29 | .return("*"); 30 | 31 | const queryResult = match.build(); 32 | 33 | expect(queryResult.cypher).toMatchInlineSnapshot(` 34 | "MATCH (this0) 35 | WHERE COUNT { 36 | MATCH (this1:Movie) 37 | RETURN * 38 | } > 10 39 | RETURN *" 40 | `); 41 | 42 | expect(queryResult.params).toMatchInlineSnapshot(`{}`); 43 | }); 44 | }); 45 | -------------------------------------------------------------------------------- /src/expressions/subquery/Count.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import type { CypherEnvironment } from "../../Environment"; 21 | import { padBlock } from "../../utils/pad-block"; 22 | import { Subquery } from "./Subquery"; 23 | 24 | /** COUNT subquery expression 25 | * @see {@link https://neo4j.com/docs/cypher-manual/current/syntax/expressions/#count-subqueries | Cypher Documentation} 26 | * @group Subqueries 27 | */ 28 | export class Count extends Subquery { 29 | /** 30 | * @internal 31 | */ 32 | public getCypher(env: CypherEnvironment): string { 33 | const subQueryStr = this.subquery.getCypher(env); 34 | const paddedSubQuery = padBlock(subQueryStr); 35 | return `COUNT {\n${paddedSubQuery}\n}`; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/expressions/subquery/Exists.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import Cypher from "../.."; 21 | 22 | describe("Exists subquery", () => { 23 | test("Exists predicate with subclause", () => { 24 | const subquery = new Cypher.Match(new Cypher.Pattern(new Cypher.Node(), { labels: ["Movie"] })).return("*"); 25 | 26 | const existsExpression = new Cypher.Exists(subquery); 27 | const match = new Cypher.Match(new Cypher.Pattern(new Cypher.Node())).where(existsExpression).return("*"); 28 | 29 | const queryResult = match.build(); 30 | 31 | expect(queryResult.cypher).toMatchInlineSnapshot(` 32 | "MATCH (this0) 33 | WHERE EXISTS { 34 | MATCH (this1:Movie) 35 | RETURN * 36 | } 37 | RETURN *" 38 | `); 39 | 40 | expect(queryResult.params).toMatchInlineSnapshot(`{}`); 41 | }); 42 | }); 43 | -------------------------------------------------------------------------------- /src/expressions/subquery/Exists.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import type { CypherEnvironment } from "../../Environment"; 21 | import { padBlock } from "../../utils/pad-block"; 22 | import { Subquery } from "./Subquery"; 23 | 24 | /** 25 | * @see {@link https://neo4j.com/docs/cypher-manual/current/syntax/expressions/#existential-subqueries | Cypher Documentation} 26 | * @group Subqueries 27 | */ 28 | export class Exists extends Subquery { 29 | /** 30 | * @internal 31 | */ 32 | public getCypher(env: CypherEnvironment): string { 33 | const subQueryStr = this.subquery.getCypher(env); 34 | const paddedSubQuery = padBlock(subQueryStr); 35 | return `EXISTS {\n${paddedSubQuery}\n}`; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/expressions/subquery/Subquery.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import { CypherASTNode } from "../../CypherASTNode"; 21 | import type { Clause } from "../../clauses/Clause"; 22 | 23 | export abstract class Subquery extends CypherASTNode { 24 | protected subquery: CypherASTNode; 25 | 26 | constructor(subquery: Clause) { 27 | super(); 28 | const rootQuery = subquery.getRoot(); 29 | this.addChildren(rootQuery); 30 | this.subquery = rootQuery; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import * as Cypher from "./Cypher"; 21 | 22 | export * from "./Cypher"; 23 | 24 | export default Cypher; 25 | -------------------------------------------------------------------------------- /src/namespaces/apoc/apoc.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | /** Functions and procedures in `apoc.date` 21 | * @see [Apoc Documentation](https://neo4j.com/docs/apoc/current/overview/apoc.date/) 22 | */ 23 | export * as date from "./date"; 24 | 25 | /** Functions and procedures in `apoc.util` 26 | * @see [Apoc Documentation](https://neo4j.com/docs/apoc/current/overview/apoc.util/) 27 | */ 28 | export * as util from "./util"; 29 | 30 | /** Functions and procedures in `apoc.cypher` 31 | * @see [Apoc Documentation](https://neo4j.com/docs/apoc/current/overview/apoc.cypher/) 32 | */ 33 | export * as cypher from "./cypher/cypher"; 34 | -------------------------------------------------------------------------------- /src/namespaces/apoc/cypher/cypher.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | export { runFirstColumnMany, runFirstColumnSingle } from "./run-first-column"; 21 | -------------------------------------------------------------------------------- /src/namespaces/apoc/date.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import { CypherFunction } from "../../expressions/functions/CypherFunctions"; 21 | import { toString } from "../../expressions/functions/string"; 22 | import { Literal } from "../../references/Literal"; 23 | import type { Expr } from "../../types"; 24 | 25 | /** 26 | * @group Functions 27 | * @see [Apoc Documentation](https://neo4j.com/docs/apoc/current/overview/apoc.date/apoc.date.convertFormat/) 28 | * @example 29 | * ```ts 30 | * Cypher.apoc.date.convertFormat( 31 | * new Cypher.Param("2020-11-04"), 32 | * "date", 33 | * "basic_date" 34 | * ) 35 | *``` 36 | */ 37 | export function convertFormat(temporalParam: Expr, currentFormat: string, convertTo = "yyyy-MM-dd"): CypherFunction { 38 | return new CypherFunction("apoc.date.convertFormat", [ 39 | toString(temporalParam), // NOTE: should this be `toString` by default? 40 | new Literal(currentFormat), 41 | new Literal(convertTo), 42 | ]); 43 | } 44 | -------------------------------------------------------------------------------- /src/namespaces/apoc/util.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import { CypherFunction } from "../../expressions/functions/CypherFunctions"; 21 | import type { ListExpr as List } from "../../expressions/list/ListExpr"; 22 | import type { MapExpr as Map } from "../../expressions/map/MapExpr"; 23 | import { VoidCypherProcedure } from "../../procedures/CypherProcedure"; 24 | import { Literal } from "../../references/Literal"; 25 | import type { Predicate } from "../../types"; 26 | import { normalizeVariable } from "../../utils/normalize-variable"; 27 | 28 | /** 29 | * @group Procedures 30 | * @see [Apoc Documentation](https://neo4j.com/docs/apoc/current/overview/apoc.util/apoc.util.validate/) 31 | */ 32 | export function validate( 33 | predicate: Predicate, 34 | message: string | Literal, 35 | params: List | Literal | Map = new Literal([0]) 36 | ): VoidCypherProcedure { 37 | const messageVar = normalizeVariable(message); 38 | return new VoidCypherProcedure("apoc.util.validate", [predicate, messageVar, params]); 39 | } 40 | 41 | /** 42 | * @group Functions 43 | * @see [Apoc Documentation](https://neo4j.com/docs/apoc/current/overview/apoc.util/apoc.util.validatePredicate/) 44 | */ 45 | export function validatePredicate(predicate: Predicate, message: string): CypherFunction { 46 | const defaultParam = new Literal([0]); 47 | 48 | return new CypherFunction("apoc.util.validatePredicate", [predicate, new Literal(message), defaultParam]); 49 | } 50 | -------------------------------------------------------------------------------- /src/namespaces/db/cdc.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import { CypherProcedure } from "../../procedures/CypherProcedure"; 21 | import type { Expr } from "../../types"; 22 | import { normalizeExpr, normalizeList } from "../../utils/normalize-variable"; 23 | 24 | const CDC_NAMESPACE = "db.cdc"; 25 | 26 | /** Acquire a change identifier for the last committed transaction 27 | * @see [Neo4j Documentation](https://neo4j.com/docs/cdc/current/procedures/current/) 28 | * @group Procedures 29 | */ 30 | export function current(): CypherProcedure<"id"> { 31 | return new CypherProcedure("current", [], CDC_NAMESPACE); 32 | } 33 | 34 | /** Acquire a change identifier for the earliest available change 35 | * @see [Neo4j Documentation](https://neo4j.com/docs/cdc/current/procedures/earliest/) 36 | * @group Procedures 37 | */ 38 | export function earliest(): CypherProcedure<"id"> { 39 | return new CypherProcedure("earliest", [], CDC_NAMESPACE); 40 | } 41 | 42 | /** Query the database for captured changes 43 | * @see [Neo4j Documentation](https://neo4j.com/docs/cdc/current/procedures/query/) 44 | * @group Procedures 45 | */ 46 | export function query( 47 | from: string | Expr, 48 | selectors: Array = [] 49 | ): CypherProcedure<"id" | "txId" | "seq" | "metadata" | "event"> { 50 | const fromExpr = normalizeExpr(from); 51 | const selectorsExpr = normalizeList(selectors); 52 | return new CypherProcedure("query", [fromExpr, selectorsExpr], CDC_NAMESPACE); 53 | } 54 | -------------------------------------------------------------------------------- /src/namespaces/db/index/dbIndex.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | export * as fulltext from "../index/fulltext"; 21 | export * as vector from "../index/vector"; 22 | -------------------------------------------------------------------------------- /src/namespaces/db/schema.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import Cypher from "../../index"; 21 | 22 | describe("db.schema procedures", () => { 23 | test("db.schema.nodeTypeProperties", () => { 24 | const query = Cypher.db.schema 25 | .nodeTypeProperties() 26 | .yield("nodeLabels", "nodeType", "propertyName", "propertyTypes", "mandatory"); 27 | const { cypher } = query.build(); 28 | 29 | expect(cypher).toMatchInlineSnapshot( 30 | `"CALL db.schema.nodeTypeProperties() YIELD nodeLabels, nodeType, propertyName, propertyTypes, mandatory"` 31 | ); 32 | }); 33 | 34 | test("db.schema.relTypeProperties", () => { 35 | const query = Cypher.db.schema 36 | .relTypeProperties() 37 | .yield("relType", "propertyName", "propertyTypes", "mandatory"); 38 | const { cypher } = query.build(); 39 | 40 | expect(cypher).toMatchInlineSnapshot( 41 | `"CALL db.schema.relTypeProperties() YIELD relType, propertyName, propertyTypes, mandatory"` 42 | ); 43 | }); 44 | test("db.schema.visualization", () => { 45 | const query = Cypher.db.schema.visualization().yield("nodes", "relationships"); 46 | const { cypher } = query.build(); 47 | 48 | expect(cypher).toMatchInlineSnapshot(`"CALL db.schema.visualization() YIELD nodes, relationships"`); 49 | }); 50 | }); 51 | -------------------------------------------------------------------------------- /src/namespaces/db/schema.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import { CypherProcedure } from "../../procedures/CypherProcedure"; 21 | 22 | const SCHEMA_NAMESPACE = "db.schema"; 23 | 24 | /** 25 | * @see [Neo4j Documentation](https://neo4j.com/docs/operations-manual/current/reference/procedures/#procedure_db_schema_nodetypeproperties) 26 | * @group Procedures 27 | */ 28 | export function nodeTypeProperties(): CypherProcedure< 29 | "nodeType" | "nodeLabels" | "propertyName" | "propertyTypes" | "mandatory" 30 | > { 31 | return new CypherProcedure("nodeTypeProperties", [], SCHEMA_NAMESPACE); 32 | } 33 | 34 | /** 35 | * @see [Neo4j Documentation](https://neo4j.com/docs/operations-manual/current/reference/procedures/#procedure_db_schema_reltypeproperties) 36 | * @group Procedures 37 | */ 38 | export function relTypeProperties(): CypherProcedure<"relType" | "propertyName" | "propertyTypes" | "mandatory"> { 39 | return new CypherProcedure("relTypeProperties", [], SCHEMA_NAMESPACE); 40 | } 41 | /** 42 | * @see [Neo4j Documentation](https://neo4j.com/docs/operations-manual/current/reference/procedures/#procedure_db_schema_visualization) 43 | * @group Procedures 44 | */ 45 | export function visualization(): CypherProcedure<"nodes" | "relationships"> { 46 | return new CypherProcedure("visualization", [], SCHEMA_NAMESPACE); 47 | } 48 | -------------------------------------------------------------------------------- /src/namespaces/genai/genai.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | export * as vector from "./vector"; 21 | -------------------------------------------------------------------------------- /src/namespaces/tx.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import Cypher from "../index"; 21 | 22 | describe("tx procedures", () => { 23 | test("tx.getMetaData", () => { 24 | const query = Cypher.tx.getMetaData().yield("metadata"); 25 | const { cypher } = query.build(); 26 | 27 | expect(cypher).toMatchInlineSnapshot(`"CALL tx.getMetaData() YIELD metadata"`); 28 | }); 29 | test("tx.setMetadata", () => { 30 | const query = Cypher.tx.setMetaData({ 31 | test: "dsa", 32 | test2: new Cypher.Param("dsa2"), 33 | }); 34 | const { cypher } = query.build(); 35 | 36 | expect(cypher).toMatchInlineSnapshot(`"CALL tx.setMetaData({ test: \\"dsa\\", test2: $param0 })"`); 37 | }); 38 | }); 39 | -------------------------------------------------------------------------------- /src/namespaces/tx.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import type { VoidCypherProcedure } from "../procedures/CypherProcedure"; 21 | import { CypherProcedure } from "../procedures/CypherProcedure"; 22 | import type { Literal } from "../references/Literal"; 23 | import type { Param } from "../references/Param"; 24 | import { normalizeMap } from "../utils/normalize-variable"; 25 | 26 | const TX_NAMESPACE = "tx"; 27 | 28 | /** 29 | * @see [Neo4j Documentation](https://neo4j.com/docs/operations-manual/current/reference/procedures/#procedure_tx_getmetadata) 30 | * @group Procedures 31 | */ 32 | export function getMetaData(): CypherProcedure<"metadata"> { 33 | return new CypherProcedure("getMetaData", [], TX_NAMESPACE); 34 | } 35 | 36 | /** 37 | * @see [Neo4j Documentation](https://neo4j.com/docs/operations-manual/current/reference/procedures/#procedure_tx_setmetadata) 38 | * @group Procedures 39 | */ 40 | export function setMetaData(data: Record): VoidCypherProcedure { 41 | return new CypherProcedure("setMetaData", [normalizeMap(data)], TX_NAMESPACE); 42 | } 43 | -------------------------------------------------------------------------------- /src/namespaces/vector/similarity.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import { CypherFunction } from "../../expressions/functions/CypherFunctions"; 21 | import type { Expr } from "../../types"; 22 | 23 | const VECTOR_SIMILARITY_NAMESPACE = "vector.similarity"; 24 | 25 | /** Returns a FLOAT representing the similarity between the argument vectors based on their Euclidean distance. 26 | * @see [Neo4j Documentation](https://neo4j.com/docs/cypher-manual/current/functions/vector/#functions-similarity-euclidean) 27 | * @group Functions 28 | * @since Neo4j 5.18 29 | */ 30 | export function euclidean(a: Expr, b: Expr): CypherFunction { 31 | return new CypherFunction("euclidean", [a, b], VECTOR_SIMILARITY_NAMESPACE); 32 | } 33 | 34 | /** Returns a FLOAT representing the similarity between the argument vectors based on their cosine. 35 | * @see [Neo4j Documentation](https://neo4j.com/docs/cypher-manual/current/functions/vector/#functions-similarity-cosine) 36 | * @group Functions 37 | * @since Neo4j 5.18 38 | */ 39 | export function cosine(a: Expr, b: Expr): CypherFunction { 40 | return new CypherFunction("cosine", [a, b], VECTOR_SIMILARITY_NAMESPACE); 41 | } 42 | -------------------------------------------------------------------------------- /src/namespaces/vector/vector.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | /** Functions and procedures in `apoc.date` 21 | * @see [Apoc Documentation](https://neo4j.com/docs/apoc/current/overview/apoc.date/) 22 | */ 23 | export * as similarity from "./similarity"; 24 | -------------------------------------------------------------------------------- /src/pattern/PathAssign.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import type { PathVariable, Pattern, QuantifiedPath } from ".."; 21 | import { CypherASTNode } from "../CypherASTNode"; 22 | import type { CypherEnvironment } from "../Environment"; 23 | 24 | /** 25 | * @group Patterns 26 | */ 27 | export class PathAssign extends CypherASTNode { 28 | private readonly variable: PathVariable; 29 | private readonly pattern: T; 30 | 31 | constructor(pattern: T, variable: PathVariable) { 32 | super(); 33 | this.addChildren(pattern); 34 | this.pattern = pattern; 35 | this.variable = variable; 36 | } 37 | 38 | public getCypher(env: CypherEnvironment): string { 39 | const patternStr = this.pattern.getCypher(env); 40 | const variableStr = this.variable.getCypher(env); 41 | 42 | return `${variableStr} = ${patternStr}`; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/pattern/labels-to-string.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import type { CypherEnvironment } from "../Environment"; 21 | import { LabelExpr } from "../expressions/labels/label-expressions"; 22 | import { addLabelToken } from "../utils/add-label-token"; 23 | import { asArray } from "../utils/as-array"; 24 | import { escapeLabel, escapeType } from "../utils/escape"; 25 | 26 | export function labelsToString(labels: string | string[] | LabelExpr, env: CypherEnvironment): string { 27 | if (labels instanceof LabelExpr) { 28 | return addLabelToken(env.config.labelOperator, labels.getCypher(env)); 29 | } else { 30 | const shouldEscape = !env.config.unsafeEscapeOptions.disableNodeLabelEscaping; 31 | const escapedLabels = shouldEscape ? asArray(labels).map(escapeLabel) : asArray(labels); 32 | 33 | return addLabelToken(env.config.labelOperator, ...escapedLabels); 34 | } 35 | } 36 | 37 | export function typeToString(type: string | LabelExpr, env: CypherEnvironment): string { 38 | if (type instanceof LabelExpr) { 39 | return addLabelToken(env.config.labelOperator, type.getCypher(env)); 40 | } else { 41 | const shouldEscape = !env.config.unsafeEscapeOptions.disableRelationshipTypeEscaping; 42 | const escapedType = shouldEscape ? escapeType(type) : type; 43 | 44 | return addLabelToken(env.config.labelOperator, escapedType); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/references/Param.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import type { CypherEnvironment } from "../Environment"; 21 | import { Variable } from "./Variable"; 22 | 23 | /** Represents a parameter that will be passed as a separate object 24 | * @group Variables 25 | */ 26 | export class Param extends Variable { 27 | public readonly value: T; 28 | 29 | constructor(value: T) { 30 | super(); 31 | this.prefix = "param"; 32 | this.value = value; 33 | } 34 | 35 | /** Defines if the Param has a value that needs to be returned by the builder */ 36 | public get hasValue(): boolean { 37 | return this.value !== undefined; 38 | } 39 | 40 | public getCypher(env: CypherEnvironment): string { 41 | if (this.isNull) { 42 | return "NULL"; 43 | } 44 | 45 | return `$${env.getReferenceId(this)}`; 46 | } 47 | 48 | public get isNull(): boolean { 49 | return this.value === null; 50 | } 51 | } 52 | 53 | /** Represents a parameter with a given name 54 | * @group Variables 55 | */ 56 | export class NamedParam extends Param { 57 | public id: string; 58 | 59 | constructor(name: string, value?: unknown) { 60 | super(value); 61 | this.id = name; 62 | } 63 | 64 | /** @internal */ 65 | public getCypher(env: CypherEnvironment): string { 66 | env.addNamedParamReference(this.id, this); 67 | return super.getCypher(env); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/references/Path.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import type { NamedReference } from "./Variable"; 21 | import { Variable } from "./Variable"; 22 | 23 | /** Reference to a path variable 24 | * @see {@link https://neo4j.com/docs/cypher-manual/current/syntax/patterns | Cypher Documentation} 25 | * @group Variables 26 | */ 27 | export class PathVariable extends Variable { 28 | constructor() { 29 | super(); 30 | this.prefix = "p"; 31 | } 32 | } 33 | 34 | /** For compatibility reasons, represents a path as a variable with the given name 35 | * @group Variables 36 | */ 37 | export class NamedPathVariable extends PathVariable implements NamedReference { 38 | public readonly id: string; 39 | 40 | constructor(name: string) { 41 | super(); 42 | this.id = name; 43 | this.prefix = ""; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/references/RelationshipRef.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import Cypher from ".."; 21 | import { TestClause } from "../utils/TestClause"; 22 | 23 | describe("RelationshipRef", () => { 24 | test("Create relationships", () => { 25 | const rel1 = new Cypher.Relationship(); 26 | const rel2 = new Cypher.Relationship(); 27 | 28 | const testClause = new TestClause(rel1, rel2); 29 | 30 | const queryResult = testClause.build(); 31 | expect(queryResult.cypher).toMatchInlineSnapshot(`"this0this1"`); 32 | }); 33 | 34 | test("Create named relationship", () => { 35 | const rel1 = new Cypher.NamedRelationship("myRel"); 36 | 37 | const testClause = new TestClause(rel1); 38 | 39 | const queryResult = testClause.build(); 40 | expect(queryResult.cypher).toMatchInlineSnapshot(`"myRel"`); 41 | expect(rel1.name).toBe("myRel"); 42 | }); 43 | }); 44 | -------------------------------------------------------------------------------- /src/references/RelationshipRef.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import { HasLabel } from "../expressions/HasLabel"; 21 | import type { LabelExpr } from "../expressions/labels/label-expressions"; 22 | import type { NamedReference } from "./Variable"; 23 | import { Variable } from "./Variable"; 24 | 25 | /** Reference to a relationship property 26 | * @group Variables 27 | */ 28 | export class RelationshipRef extends Variable { 29 | constructor() { 30 | super(); 31 | this.prefix = "this"; 32 | } 33 | 34 | public hasType(label: string | LabelExpr): HasLabel { 35 | if (typeof label === "string") { 36 | return new HasLabel(this, [label]); 37 | } else { 38 | return new HasLabel(this, label); 39 | } 40 | } 41 | } 42 | 43 | /** Represents a relationship reference with a given name 44 | * @group Variables 45 | */ 46 | export class NamedRelationship extends RelationshipRef implements NamedReference { 47 | public readonly id: string; 48 | 49 | constructor(id: string) { 50 | super(); 51 | this.id = id; 52 | } 53 | 54 | public get name(): string { 55 | return this.id; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/utils/TestClause.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import { Clause } from "../clauses/Clause"; 21 | import type { CypherEnvironment } from "../Environment"; 22 | import type { CypherCompilable } from "../types"; 23 | 24 | /** For testing purposes only */ 25 | export class TestClause extends Clause { 26 | private readonly children: CypherCompilable[]; 27 | 28 | constructor(...children: CypherCompilable[]) { 29 | super(); 30 | this.children = children; 31 | } 32 | 33 | public getCypher(env: CypherEnvironment): string { 34 | return this.children.map((c) => c.getCypher(env)).join(""); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/utils/add-label-token.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import { addLabelToken } from "./add-label-token"; 21 | 22 | describe.each([":", "&"] as const)("addLabelToken", (operator) => { 23 | test("addLabelToken without labels using operator %s", () => { 24 | const result = addLabelToken(operator); 25 | expect(result).toBe(""); 26 | }); 27 | 28 | test("addLabelToken with a single label using operator %s", () => { 29 | const result = addLabelToken(operator, "Movie"); 30 | expect(result).toBe(":Movie"); 31 | }); 32 | 33 | test("addLabelToken with two labels using operator %s", () => { 34 | const result = addLabelToken(operator, "Movie", "Film"); 35 | expect(result).toBe(`:Movie${operator}Film`); 36 | }); 37 | 38 | test("addLabelToken with multiple labels using operator %s", () => { 39 | const result = addLabelToken(operator, "Movie", "Film", "Video"); 40 | expect(result).toBe(`:Movie${operator}Film${operator}Video`); 41 | }); 42 | }); 43 | -------------------------------------------------------------------------------- /src/utils/add-label-token.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | /** Generates a string with all the labels. For example `:Movie&Film` */ 21 | export function addLabelToken(andToken: ":" | "&", ...labels: string[]): string { 22 | const firstLabel = labels.shift(); 23 | if (!firstLabel) return ""; 24 | 25 | const extraLabels = labels.map((label) => `${andToken}${label}`).join(""); 26 | 27 | return `:${firstLabel}${extraLabels}`; 28 | } 29 | -------------------------------------------------------------------------------- /src/utils/as-array.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import { asArray } from "./as-array"; 21 | 22 | describe("asArray", () => { 23 | test("get array from array", () => { 24 | const result = asArray([1, 2]); 25 | expect(result).toEqual([1, 2]); 26 | }); 27 | 28 | test("get array from null", () => { 29 | const result = asArray(null); 30 | expect(result).toEqual([]); 31 | }); 32 | 33 | test("get array from undefined", () => { 34 | const result = asArray(undefined); 35 | expect(result).toEqual([]); 36 | }); 37 | 38 | test("get array from object", () => { 39 | const result = asArray({}); 40 | expect(result).toEqual([{}]); 41 | }); 42 | 43 | test("get array from number", () => { 44 | const result = asArray(3); 45 | expect(result).toEqual([3]); 46 | }); 47 | }); 48 | -------------------------------------------------------------------------------- /src/utils/as-array.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | /** Makes sure input is an array, if not it turns into an array (empty array if input is null or undefined) */ 21 | export function asArray(raw: T | Array | undefined | null): Array { 22 | if (Array.isArray(raw)) return raw; 23 | if (raw === undefined || raw === null) return []; 24 | return [raw]; 25 | } 26 | -------------------------------------------------------------------------------- /src/utils/compile-cypher-if-exists.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import type { CypherEnvironment } from "../Environment"; 21 | import type { CypherCompilable } from "../types"; 22 | 23 | /** Compiles the cypher of an element, if the resulting cypher is not empty adds a prefix */ 24 | export function compileCypherIfExists( 25 | element: CypherCompilable | undefined, 26 | env: CypherEnvironment, 27 | { prefix = "", suffix = "" }: { prefix?: string; suffix?: string } = {} 28 | ): string { 29 | if (!element) return ""; 30 | const cypher = element.getCypher(env); 31 | if (!cypher) return ""; 32 | return `${prefix}${cypher}${suffix}`; 33 | } 34 | -------------------------------------------------------------------------------- /src/utils/concat.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import type { Clause } from "../clauses/Clause"; 21 | import { CompositeClause } from "../clauses/utils/concat"; 22 | 23 | /** Concatenates multiple {@link Clause | clauses} into a single clause 24 | */ 25 | export function concat(...clauses: Array): CompositeClause { 26 | return new CompositeClause(clauses, "\n"); 27 | } 28 | -------------------------------------------------------------------------------- /src/utils/filter-truthy.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | /** Filter all elements in an array, only leaving truthy values */ 21 | export function filterTruthy(arr: Array): Array { 22 | return arr.filter((v): v is T => !!v); 23 | } 24 | -------------------------------------------------------------------------------- /src/utils/is-cypher-compilable.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import type { CypherCompilable } from "../types"; 21 | 22 | export function isCypherCompilable(value: unknown): value is CypherCompilable { 23 | // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access 24 | return Boolean(typeof (value as any)?.getCypher === "function"); 25 | } 26 | -------------------------------------------------------------------------------- /src/utils/is-number.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | /** Check if something is a number */ 21 | export function isNumber(n: unknown): n is number { 22 | return typeof n === "number" && !Number.isNaN(n); 23 | } 24 | -------------------------------------------------------------------------------- /src/utils/is-string.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | /** Checks if value is string */ 21 | export function isString(value: unknown): value is string { 22 | return typeof value === "string"; 23 | } 24 | -------------------------------------------------------------------------------- /src/utils/normalize-variable.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import Cypher from ".."; 21 | import { normalizeVariable } from "./normalize-variable"; 22 | 23 | describe("normalizeVariable", () => { 24 | test("returns the same variable if it is a CypherCompilable", () => { 25 | const originalVariable = new Cypher.Literal("hello"); 26 | const result = normalizeVariable(originalVariable); 27 | 28 | expect(result).toEqual(originalVariable); 29 | }); 30 | 31 | test("generates a new literal variable if it is a primitive value", () => { 32 | const result = normalizeVariable(5); 33 | 34 | expect(result).toBeInstanceOf(Cypher.Literal); 35 | }); 36 | }); 37 | -------------------------------------------------------------------------------- /src/utils/normalize-variable.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import { ListExpr } from "../expressions/list/ListExpr"; 21 | import { MapExpr } from "../expressions/map/MapExpr"; 22 | import { Literal } from "../references/Literal"; 23 | import type { Param } from "../references/Param"; 24 | import type { Variable } from "../references/Variable"; 25 | import type { Expr } from "../types"; 26 | import { isCypherCompilable } from "./is-cypher-compilable"; 27 | 28 | type VariableInput = string | number | Variable | Literal | Param; 29 | 30 | export function normalizeVariable(value: VariableInput): Variable | Literal | Param { 31 | if (isCypherCompilable(value)) return value; 32 | return new Literal(value); 33 | } 34 | 35 | // Same as normalizeVariable, just typings are different 36 | export function normalizeExpr(value: VariableInput | Expr): Variable | Literal | Param | Expr { 37 | if (isCypherCompilable(value)) return value; 38 | return new Literal(value); 39 | } 40 | 41 | export function normalizeMap(map: Record): MapExpr { 42 | return Object.entries(map).reduce((mapExpr, [key, value]) => { 43 | mapExpr.set(key, normalizeVariable(value)); 44 | return mapExpr; 45 | }, new MapExpr()); 46 | } 47 | 48 | export function normalizeList(list: Array): ListExpr { 49 | const expressions = list.map((v) => normalizeExpr(v)); 50 | return new ListExpr(expressions); 51 | } 52 | -------------------------------------------------------------------------------- /src/utils/pad-block.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | export function padBlock(block: string, spaces = 4): string { 21 | const paddingStr = " ".repeat(spaces); 22 | const paddedNewLines = block.replace(/\n/g, `\n${paddingStr}`); 23 | return `${paddingStr}${paddedNewLines}`; 24 | } 25 | -------------------------------------------------------------------------------- /src/utils/pad-left.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import { padLeft } from "./pad-left"; 21 | 22 | describe("padLeft", () => { 23 | test("pads string", () => { 24 | expect(padLeft("my string")).toBe(" my string"); 25 | expect(padLeft(" my string")).toBe(" my string"); 26 | }); 27 | 28 | test("returns empty string if input is undefined or empty string", () => { 29 | expect(padLeft(undefined)).toBe(""); 30 | expect(padLeft("")).toBe(""); 31 | }); 32 | }); 33 | -------------------------------------------------------------------------------- /src/utils/pad-left.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | /** Adds spaces to the left of the string, returns empty string if variable is undefined or empty string */ 21 | export function padLeft(str: string | undefined): string { 22 | if (!str) return ""; 23 | return ` ${str}`; 24 | } 25 | -------------------------------------------------------------------------------- /src/utils/serialize-map.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import Cypher from ".."; 21 | import { CypherEnvironment } from "../Environment"; 22 | import { serializeMap } from "./serialize-map"; 23 | 24 | describe("serializeMap", () => { 25 | const env = new CypherEnvironment(); 26 | const map = new Map([ 27 | ["test", new Cypher.Literal(10)], 28 | ["test$", new Cypher.Literal(10)], 29 | ["expr", Cypher.reverse(new Cypher.Literal([1]))], 30 | ]); 31 | 32 | test("serialize a map of expressions", () => { 33 | const result = serializeMap(env, map); 34 | expect(result).toBe("{ test: 10, `test$`: 10, expr: reverse([1]) }"); 35 | }); 36 | 37 | test("serialize a map of expressions without curly braces", () => { 38 | const result = serializeMap(env, map, true); 39 | expect(result).toBe("test: 10, `test$`: 10, expr: reverse([1])"); 40 | }); 41 | }); 42 | -------------------------------------------------------------------------------- /src/utils/serialize-map.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import type { Expr } from "../types"; 21 | import type { CypherEnvironment } from "../Environment"; 22 | import { escapeProperty } from "./escape"; 23 | 24 | export function serializeMap(env: CypherEnvironment, map: Map, omitCurlyBraces = false): string { 25 | const serializedFields: string[] = []; 26 | 27 | for (const [key, value] of map.entries()) { 28 | if (value) { 29 | const fieldStr = `${escapeProperty(key)}: ${value.getCypher(env)}`; 30 | serializedFields.push(fieldStr); 31 | } 32 | } 33 | 34 | const serializedContent = serializedFields.join(", "); 35 | if (omitCurlyBraces) return serializedContent; 36 | return `{ ${serializedContent} }`; 37 | } 38 | -------------------------------------------------------------------------------- /src/utils/stringify-object.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import { stringifyObject } from "./stringify-object"; 21 | 22 | describe("stringifyObject", () => { 23 | test("creates a valid cypher object from a js object", () => { 24 | const result = stringifyObject({ 25 | this: "this", 26 | that: `"that"`, 27 | }); 28 | 29 | expect(result).toBe(`{ this: this, that: "that" }`); 30 | }); 31 | 32 | test("ignores undefined, null and empty string values", () => { 33 | const result = stringifyObject({ 34 | nobody: "expects", 35 | the: undefined, 36 | spanish: null, 37 | inquisition: "", 38 | }); 39 | 40 | expect(result).toBe(`{ nobody: expects }`); 41 | }); 42 | 43 | test("escape keys", () => { 44 | const result = stringifyObject({ 45 | ["this name"]: "this", 46 | that: `"that"`, 47 | }); 48 | 49 | expect(result).toBe(`{ \`this name\`: this, that: "that" }`); 50 | }); 51 | }); 52 | -------------------------------------------------------------------------------- /src/utils/stringify-object.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import { escapeProperty } from "./escape"; 21 | 22 | /** Serializes object into a string for Cypher objects */ 23 | export function stringifyObject(fields: Record): string { 24 | return `{ ${Object.entries(fields) 25 | .filter(([, value]) => Boolean(value)) 26 | .map(([key, value]): string | undefined => { 27 | return `${escapeProperty(key)}: ${value}`; 28 | }) 29 | .join(", ")} }`; 30 | } 31 | -------------------------------------------------------------------------------- /src/utils/to-cypher-params.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import { Param } from "../references/Param"; 21 | 22 | /** Converts an object into an object of Param so it can easily be passed to a pattern. */ 23 | export function toCypherParams(original: Record): Record> { 24 | return Object.entries(original).reduce>>((acc, [key, value]) => { 25 | acc[key] = new Param(value); 26 | return acc; 27 | }, {}); 28 | } 29 | -------------------------------------------------------------------------------- /src/utils/type-helpers.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | export type ValueOf = T[keyof T]; 21 | -------------------------------------------------------------------------------- /src/utils/utils.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | // Note: This file exists for exported utils to the user 21 | 22 | export { concat } from "./concat"; 23 | export { escapeLabel, escapeProperty, escapeType, escapeVariable } from "./escape"; 24 | export { toCypherParams } from "./to-cypher-params"; 25 | -------------------------------------------------------------------------------- /tests/build-config/cypher-version.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import Cypher from "../../src"; 21 | 22 | describe("Cypher version", () => { 23 | test("Add cypher version on .build", () => { 24 | const movieNode = new Cypher.Node(); 25 | const pattern = new Cypher.Pattern(movieNode, { labels: ["Movie"] }); 26 | 27 | const matchQuery = new Cypher.Match(pattern) 28 | .where(movieNode, { 29 | title: new Cypher.Param("The Matrix"), 30 | }) 31 | .return(movieNode.property("title")); 32 | 33 | const { cypher } = matchQuery.build({ 34 | cypherVersion: "5", 35 | }); 36 | 37 | expect(cypher).toMatchInlineSnapshot(` 38 | "CYPHER 5 39 | MATCH (this0:Movie) 40 | WHERE this0.title = $param0 41 | RETURN this0.title" 42 | `); 43 | }); 44 | }); 45 | -------------------------------------------------------------------------------- /tests/build-config/label-operator.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) "Neo4j" 3 | * Neo4j Sweden AB [http://neo4j.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import Cypher from "../../src"; 21 | import { TestClause } from "../../src/utils/TestClause"; 22 | 23 | describe.each([":", "&"] as const)("Config.labelOperator", (labelOperator) => { 24 | test("Pattern", () => { 25 | const node = new Cypher.Node(); 26 | const query = new Cypher.Match(new Cypher.Pattern(node, { labels: ["Movie", "Film"] })); 27 | 28 | const queryResult = new TestClause(query).build({ 29 | labelOperator, 30 | }); 31 | 32 | expect(queryResult.cypher).toBe(`MATCH (this0:Movie${labelOperator}Film)`); 33 | }); 34 | 35 | test("hasLabel", () => { 36 | const node = new Cypher.Node(); 37 | const query = new Cypher.Match(new Cypher.Pattern(node, { labels: ["Movie"] })).where( 38 | node.hasLabels("Movie", "Film") 39 | ); 40 | 41 | const queryResult = new TestClause(query).build({ 42 | labelOperator, 43 | }); 44 | 45 | expect(queryResult.cypher).toBe(`MATCH (this0:Movie) 46 | WHERE this0:Movie${labelOperator}Film`); 47 | }); 48 | }); 49 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@tsconfig/node16/tsconfig.json", 3 | "compilerOptions": { 4 | "declaration": true, 5 | "declarationMap": true, 6 | "sourceMap": true, 7 | "resolveJsonModule": true, 8 | "experimentalDecorators": true, 9 | "noImplicitAny": true, 10 | "rootDir": ".", 11 | "baseUrl": ".", 12 | "outDir": "dist", 13 | "stripInternal": false, // TODO: Change this after validating output .d.ts 14 | "noUncheckedIndexedAccess": true 15 | }, 16 | "include": ["src/**/*", "tests/**/*", "global.d.ts"] 17 | } 18 | -------------------------------------------------------------------------------- /tsconfig.production.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "rootDir": "src", 5 | "outDir": "dist", 6 | "declarationMap": false, 7 | "sourceMap": false 8 | }, 9 | "exclude": ["src/**/*.test.ts"], 10 | "include": ["src/**/*"] 11 | } 12 | -------------------------------------------------------------------------------- /tsdoc.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://developer.microsoft.com/json-schemas/tsdoc/v0/tsdoc.schema.json", 3 | "extends": ["typedoc/tsdoc.json"], 4 | "tagDefinitions": [] 5 | } 6 | -------------------------------------------------------------------------------- /typedoc.json: -------------------------------------------------------------------------------- 1 | { 2 | "excludeExternals": true, 3 | "excludePrivate": true, 4 | "excludeProtected": true, 5 | "includeVersion": true, 6 | "excludeInternal": true, 7 | "excludeTags": [], 8 | "hideGenerator": true, 9 | "name": "Cypher Builder", 10 | "visibilityFilters": {}, 11 | "sidebarLinks": { 12 | // "Cypher Builder Manual": "https://neo4j.github.io/cypher-builder" 13 | }, 14 | "gitRemote": "origin", 15 | "out": "./docs/build/site/reference", 16 | "readme": "none", 17 | "highlightLanguages": ["css", "html", "javascript", "json", "jsonc", "json5", "tsx", "typescript", "cypher"], 18 | "validation": { 19 | "invalidLink": true 20 | }, 21 | "intentionallyNotExported": ["CypherCompilable", "NamedReference", "MatchClausePattern"], 22 | "navigation": { 23 | "includeCategories": true, 24 | "includeGroups": true 25 | }, 26 | "categorizeByGroup": true, 27 | "groupOrder": [ 28 | "Clauses", 29 | "Subqueries", 30 | "Patterns", 31 | "Variables", 32 | "Functions", 33 | "Procedures", 34 | "Namespaces", 35 | "Expressions", 36 | "Operators", 37 | "Maps", 38 | "Lists", 39 | "Utils" 40 | ] 41 | } 42 | --------------------------------------------------------------------------------