├── .changeset ├── README.md └── config.json ├── .github ├── issue_template.md ├── pull_request_template.md └── workflows │ ├── changeset-pr-or-release.yml │ ├── playwright.yml │ └── reusable │ ├── env-setup │ └── action.yml │ └── playwright-browsers │ └── action.yml ├── .gitignore ├── .nvmrc ├── .prettierignore ├── .prettierrc ├── LICENSE ├── README.md ├── api-docdown.json ├── apps └── svelte-ts │ ├── .gitignore │ ├── .vscode │ └── extensions.json │ ├── CHANGELOG.md │ ├── README.md │ ├── index.html │ ├── package.json │ ├── src │ ├── App.svelte │ ├── ConnectModal.svelte │ ├── CopyIcon.svelte │ ├── command.utils.ts │ ├── cypher.utils.ts │ ├── frames │ │ ├── Cypher.svelte │ │ ├── Generic.svelte │ │ └── Generic.types.ts │ ├── history.store.ts │ ├── main.ts │ ├── style.css │ └── vite-env.d.ts │ ├── svelte.config.js │ ├── tsconfig.json │ ├── tsconfig.node.json │ └── vite.config.ts ├── babel.antlr4-browser.config.js ├── babel.antlr4.config.js ├── babel.config.js ├── babel.es6.config.js ├── babel.react.config.js ├── demos ├── demo-base-react │ ├── CHANGELOG.md │ ├── README.md │ ├── package.json │ └── src │ │ ├── App.js │ │ ├── Database.js │ │ └── index.js ├── demo-base-svelte │ ├── CHANGELOG.md │ ├── README.md │ ├── package.json │ └── src │ │ ├── App.svelte │ │ ├── Database.svelte │ │ └── index.js ├── demo-base │ ├── CHANGELOG.md │ ├── README.md │ ├── css │ │ └── app.css │ ├── package.json │ └── src │ │ ├── index.js │ │ └── schema-data.js ├── demo-codemirror-6-vite-svelte │ ├── CHANGELOG.md │ ├── index.html │ ├── package.json │ ├── public │ │ └── vite.svg │ ├── src │ │ ├── App.svelte │ │ ├── main.ts │ │ └── vite-env.d.ts │ ├── svelte.config.js │ ├── tsconfig.json │ ├── tsconfig.node.json │ └── vite.config.ts ├── demo-codemirror-6-webpack-react │ ├── CHANGELOG.md │ ├── package.json │ ├── src │ │ ├── App.js │ │ ├── index.html │ │ └── main.js │ ├── webpack.config.js │ └── webpack.local.config.js ├── demo-codemirror-6-webpack-svelte │ ├── CHANGELOG.md │ ├── package.json │ ├── public │ │ └── vite.svg │ ├── src │ │ ├── App.svelte │ │ ├── index.html │ │ └── main.js │ ├── svelte.config.js │ ├── tsconfig.json │ ├── tsconfig.node.json │ ├── webpack.config.js │ └── webpack.local.config.js └── demo-vitest │ ├── CHANGELOG.md │ ├── index.html │ ├── package.json │ ├── public │ └── vite.svg │ ├── src │ ├── App.test.tsx │ ├── App.tsx │ ├── main.tsx │ └── testUtils │ │ └── setup.ts │ ├── tsconfig.json │ ├── tsconfig.node.json │ └── vite.config.ts ├── docs └── generated │ ├── index.md │ ├── neo4j-cypher_codemirror.md │ ├── neo4j-cypher_editor-support.md │ ├── neo4j-cypher_react-codemirror.md │ └── neo4j-cypher_svelte-codemirror.md ├── e2e-tests └── events.spec.js ├── package-lock.json ├── package.json ├── packages ├── antlr4-browser │ ├── CHANGELOG.md │ ├── package.json │ └── src │ │ └── index.js ├── antlr4-simple │ ├── CHANGELOG.md │ ├── README.md │ ├── package.json │ └── src │ │ ├── Cypher.g4 │ │ ├── CypherLexer.js │ │ ├── CypherListener.js │ │ ├── CypherParser.js │ │ └── index.js ├── antlr4 │ ├── CHANGELOG.md │ ├── README.md │ ├── package.json │ └── src │ │ ├── Cypher.g4 │ │ ├── CypherLexer.js │ │ ├── CypherListener.js │ │ ├── CypherParser.js │ │ ├── antlr-4.10.1-complete.jar │ │ └── index.js ├── codemirror │ ├── CHANGELOG.md │ ├── README.md │ ├── css │ │ └── cypher-codemirror.css │ ├── package.json │ └── src │ │ ├── codemirror.d.ts │ │ ├── codemirror.js │ │ ├── cypher-codemirror-base.js │ │ ├── cypher-extensions.js │ │ ├── cypher-state-definitions.js │ │ ├── cypher-state-selectors.js │ │ └── cypher.js ├── editor-support │ ├── CHANGELOG.md │ ├── README.md │ ├── package.json │ └── src │ │ ├── CypherEditorSupport.js │ │ ├── completion │ │ ├── AutoCompletion.js │ │ ├── CompletionTypeResolver.js │ │ ├── CompletionTypes.js │ │ └── rules │ │ │ ├── index.js │ │ │ ├── ruleCallClauseBeginning.js │ │ │ ├── ruleCheckParent.js │ │ │ ├── ruleConsoleCommandSubcommands.js │ │ │ ├── ruleLiteralEntry.js │ │ │ ├── ruleNodePattern.js │ │ │ ├── ruleNoop.js │ │ │ ├── ruleParamStartsWithDollar.js │ │ │ ├── rulePossibleKeyword.js │ │ │ ├── ruleProcedureOutputsInCallClause.js │ │ │ ├── rulePropInMapLiteral.js │ │ │ ├── rulePropertyLookup.js │ │ │ ├── ruleRelationshipPattern.js │ │ │ └── ruleVariableInExpressionPossibleFunction.js │ │ ├── editor-support.d.ts │ │ ├── editor-support.js │ │ ├── errors │ │ └── ErrorListener.js │ │ ├── highlight │ │ └── CypherSyntaxHighlight.js │ │ ├── lang │ │ ├── CypherKeywords.js │ │ └── CypherTypes.js │ │ ├── references │ │ ├── ReferencesListener.js │ │ └── ReferencesProvider.js │ │ └── util │ │ ├── PositionConverter.js │ │ ├── TreeUtils.js │ │ ├── createCypherLexer.js │ │ ├── ecsapeCypher.js │ │ ├── parse.js │ │ └── retryOperation.js ├── extract-statements │ ├── CHANGELOG.md │ ├── package.json │ └── src │ │ ├── ReferencesListener.simple.js │ │ ├── extractStatements.js │ │ ├── index.d.ts │ │ └── index.js ├── react-codemirror │ ├── CHANGELOG.md │ ├── README.md │ ├── package.json │ └── src │ │ ├── CypherEditor.d.ts │ │ ├── CypherEditor.js │ │ ├── react-codemirror.d.ts │ │ └── react-codemirror.js └── svelte-codemirror │ ├── CHANGELOG.md │ ├── README.md │ ├── package.json │ └── src │ ├── CypherEditor.svelte │ ├── CypherEditor.svelte.d.ts │ ├── svelte-codemirror.d.ts │ └── svelte-codemirror.js ├── playwright.config.js └── turbo.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.2.0/schema.json", 3 | "changelog": "@changesets/cli/changelog", 4 | "commit": false, 5 | "fixed": [], 6 | "linked": [], 7 | "access": "public", 8 | "baseBranch": "main", 9 | "updateInternalDependencies": "patch", 10 | "ignore": [], 11 | "privatePackages": { "version": true, "tag": false } 12 | } 13 | -------------------------------------------------------------------------------- /.github/issue_template.md: -------------------------------------------------------------------------------- 1 | 7 | 8 | ### Reproduce Steps 9 | 10 | 11 | 12 | ### Expected Behavior 13 | 14 | 15 | 20 | 21 | 22 | ### Can you propose a solution? 23 | 24 | What needs to be done to address this issue? Ideally, provide a pull request with a fix. 25 | 26 | ### Your Environment 27 | 28 | 29 | 30 | | software name | version | 31 | | ------------- | ------- | 32 | | | 33 | | Browser | 34 | | node.js | 35 | | npm | 36 | 37 | ### Additional Information 38 | 39 | Any additional information, configuration or data that might be necessary to reproduce the issue. 40 | 41 | For enhancements or other issues, please describe in as much detail as possible how the app should be changed and how this would benefit users/developers. 42 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | ### Please don't delete this checklist! Before submitting the PR, please make sure you do the following: 2 | 3 | - [ ] This message body should clearly illustrate what problems it solves. 4 | - [ ] Ideally, include a test that fails without this PR but passes with it. 5 | 6 | ### Tests 7 | 8 | - [ ] Run the tests locally to make sure they pass before opening the PR. 9 | 10 | ### Changesets 11 | 12 | - [ ] If your PR makes a change that should be noted in one or more packages' changelogs, generate a changeset by running `npx changeset` and following the instructions. Consult the maintainers if you're unsure what type of version bump the PR should generate. 13 | -------------------------------------------------------------------------------- /.github/workflows/changeset-pr-or-release.yml: -------------------------------------------------------------------------------- 1 | name: Create changeset PR or Release 2 | 3 | on: 4 | workflow_dispatch: 5 | push: 6 | branches: 7 | - main 8 | 9 | concurrency: ${{ github.workflow }}-${{ github.ref }} 10 | 11 | jobs: 12 | pr-or-release: 13 | name: Changeset or Release 14 | runs-on: ubuntu-latest 15 | steps: 16 | - name: Checkout Repo 17 | uses: actions/checkout@v3 18 | with: 19 | fetch-depth: 0 20 | 21 | - name: Setup node / npm env and install deps 22 | uses: ./.github/workflows/reusable/env-setup 23 | 24 | - name: Create Release Pull Request or Publish to npm if no pending changes 25 | id: changesets 26 | uses: changesets/action@v1 27 | with: 28 | version: npm run release 29 | publish: npm run publish 30 | title: Upcoming package versions and changelogs 31 | env: 32 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 33 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }} 34 | -------------------------------------------------------------------------------- /.github/workflows/playwright.yml: -------------------------------------------------------------------------------- 1 | name: Playwright Tests 2 | on: 3 | push: 4 | branches: [main] 5 | pull_request: 6 | branches: [main] 7 | jobs: 8 | test: 9 | timeout-minutes: 60 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Checkout Repo 13 | uses: actions/checkout@v3 14 | with: 15 | fetch-depth: 0 16 | 17 | - name: Setup node / npm env and install deps 18 | uses: ./.github/workflows/reusable/env-setup 19 | 20 | - name: Build 21 | run: | 22 | npm run build:libs 23 | npm run build:demos 24 | 25 | - name: Warmup pm2 26 | run: npx pm2 list 27 | 28 | - name: Install Playwright Browsers 29 | uses: ./.github/workflows/reusable/playwright-browsers 30 | 31 | - name: Run Playwright tests 32 | run: npm run start:e2e 33 | 34 | - name: Cleanup 35 | if: always() 36 | run: npm run stop:e2e 37 | 38 | - uses: actions/upload-artifact@v3 39 | if: always() 40 | with: 41 | name: playwright-results 42 | path: playwright-results/ 43 | retention-days: 30 44 | -------------------------------------------------------------------------------- /.github/workflows/reusable/env-setup/action.yml: -------------------------------------------------------------------------------- 1 | name: 'Reusable Env Setup' 2 | description: 'Composite action to setup npm, node and caches.' 3 | inputs: 4 | NODE_VERSION: 5 | description: 'Node version' 6 | required: false 7 | default: 18.x 8 | 9 | runs: 10 | using: 'composite' 11 | steps: 12 | - name: Turbo Cache 13 | id: turbo-cache 14 | uses: actions/cache@v3 15 | with: 16 | path: node_modules/.cache/turbo 17 | key: ${{ runner.os }}-turbo-${{ github.job }}-${{ github.ref_name }}-${{ github.sha }} 18 | restore-keys: | 19 | ${{ runner.os }}-turbo-${{ github.job }}-${{ github.ref_name }}- 20 | 21 | - uses: actions/setup-node@v3 22 | with: 23 | node-version: ${{ inputs.NODE_VERSION }} 24 | cache: 'npm' 25 | 26 | - name: Install dependencies 27 | shell: bash 28 | run: npm ci 29 | -------------------------------------------------------------------------------- /.github/workflows/reusable/playwright-browsers/action.yml: -------------------------------------------------------------------------------- 1 | name: 'Reusable Playwright browser cache' 2 | description: 'Composite action to setup playwright and caches.' 3 | 4 | runs: 5 | using: 'composite' 6 | steps: 7 | - name: Playwright browser cache 8 | id: playwright-cache 9 | uses: actions/cache@v3 10 | with: 11 | path: ~/.cache/ms-playwright 12 | key: ${{ runner.os }}-playwright-${{ hashFiles('**/package-lock.json') }} 13 | - name: Install with deps 14 | shell: bash 15 | run: npx playwright install --with-deps 16 | if: steps.playwright-cache.outputs.cache-hit != 'true' 17 | - name: Install deps only 18 | shell: bash 19 | run: npx playwright install-deps 20 | if: steps.playwright-cache.outputs.cache-hit == 'true' 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | *.tgz 10 | 11 | .yarn/cache 12 | .yarn/*.gz 13 | node_modules 14 | lib 15 | es 16 | dist 17 | dist-ssr 18 | *.local 19 | 20 | # Editor directories and files 21 | .vscode/* 22 | !.vscode/extensions.json 23 | .idea 24 | .DS_Store 25 | *.suo 26 | *.ntvs* 27 | *.njsproj 28 | *.sln 29 | *.sw? 30 | 31 | /playwright-results/ 32 | /playwright/.cache/ 33 | .env 34 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | 18 2 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | **/.git 2 | **/.svn 3 | **/.hg 4 | **/node_modules 5 | packages/cypher-antlr4/src/Cypher* 6 | packages/cypher-antlr4-simple/src/Cypher* 7 | lib 8 | es 9 | dist 10 | playwright-results 11 | docs 12 | .github 13 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "trailingComma": "none", 3 | "tabWidth": 2, 4 | "printWidth": 80, 5 | "overrides": [ 6 | { 7 | "files": ["*.css"], 8 | "options": { 9 | "tabWidth": 4 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### cypher-editor 2 | 3 | ### How to use 4 | 5 | Go to the relevant docs in the [docs/generated](./docs/generated) folder to read the docs on the package you're about to use. 6 | 7 | Shortcuts: 8 | [React](https://github.com/neo4j/cypher-editor/blob/main/docs/generated/neo4j-cypher_react-codemirror.md) 9 | 10 | ```bash 11 | npm install @neo4j-cypher/react-codemirror 12 | ``` 13 | 14 | [Svelte](https://github.com/neo4j/cypher-editor/blob/main/docs/generated/neo4j-cypher_svelte-codemirror.md) 15 | 16 | ```bash 17 | npm install @neo4j-cypher/svelte-codemirror 18 | ``` 19 | 20 | ### Styling the view components 21 | 22 | To make the view components build tool agnostic, the CSS is separate since importing CSS isn't a thing in many tools. 23 | If your build tool supports importing CSS, you can import like this: 24 | 25 | ```js 26 | import "@neo4j-cypher/codemirror/css/cypher-codemirror.css"; 27 | ``` 28 | 29 | If not, you can load the styles from a CDN in your HTML like: 30 | 31 | ```html 32 | 36 | ``` 37 | 38 | ### Cloning 39 | 40 | This repository is a monorepo, and all packages are located in the `packages` directory. 41 | 42 | To install the dependencies for the monorepo, run the following the base directory: 43 | 44 | ``` 45 | npm install 46 | ``` 47 | 48 | Optionally to build all library packages for release preparation, run the following in the base directory: 49 | 50 | ``` 51 | npm run build:libs 52 | ``` 53 | 54 | ### Demos 55 | 56 | Once you have install the dependencies, you can run any of the demos that are in `demo-` prefixed packages, using commands like the following: 57 | 58 | ``` 59 | cd packages/demo-codemirror-6-vite-svelte 60 | npm run start 61 | ``` 62 | 63 | ### Tests 64 | 65 | Some e2e tests are setup. You can run them indivudually in each package: 66 | 67 | ```bash 68 | cd packages/ 69 | 70 | # for dev 71 | npm run start 72 | npm run e2e 73 | 74 | # for prod 75 | npm run build 76 | npm run serve 77 | npm run e2e 78 | npm run unserve 79 | ``` 80 | 81 | Or all packages together: 82 | 83 | ```bash 84 | # in project root 85 | 86 | # for prod 87 | npm run start:e2e 88 | npm run stop:e2e 89 | ``` 90 | 91 | # Contribution process 92 | 93 | Contributions are very much appreciated and here's an outline of the process. 94 | 95 | - Work in your own fork of the repo 96 | - Open a PR against the main branch 97 | - Follow the instructions in the pull request template (run `npx changeset`) 98 | -------------------------------------------------------------------------------- /api-docdown.json: -------------------------------------------------------------------------------- 1 | { 2 | "docRootDir": ".", 3 | "docApiDir": "docs/apis", 4 | "docMarkdownDir": "docs/generated", 5 | 6 | "generateApi": false, 7 | 8 | "operation": "generate", 9 | "showInheritedMembers": false, 10 | "newlineKind": "crlf", 11 | 12 | "markdownOptions": { 13 | "fileLevel": "package", 14 | "indexFilename": "index", 15 | "indexTitle": "API Reference", 16 | "indexBreadcrumbTitle": "Home", 17 | "showPropertyDefaults": true, 18 | "hideEmptyTableColumns": true, 19 | "showBreadcrumb": true 20 | }, 21 | 22 | "includePackageNames": [], 23 | "excludePackageNames": [ 24 | "antlr4*", 25 | "extract-statements*", 26 | "demo-*", 27 | "svelte-ts" 28 | ] 29 | } 30 | -------------------------------------------------------------------------------- /apps/svelte-ts/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /apps/svelte-ts/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": ["svelte.svelte-vscode"] 3 | } 4 | -------------------------------------------------------------------------------- /apps/svelte-ts/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # svelte-ts 2 | 3 | ## 1.0.5 4 | 5 | ### Patch Changes 6 | 7 | - @neo4j-cypher/svelte-codemirror@1.0.5 8 | 9 | ## 1.0.4 10 | 11 | ### Patch Changes 12 | 13 | - Updated dependencies [eaf7435] 14 | - Updated dependencies [44d7f5f] 15 | - @neo4j-cypher/svelte-codemirror@1.0.4 16 | 17 | ## 1.0.3 18 | 19 | ### Patch Changes 20 | 21 | - Updated dependencies [f14489b] 22 | - @neo4j-cypher/svelte-codemirror@1.0.3 23 | 24 | ## 1.0.2 25 | 26 | ### Patch Changes 27 | 28 | - Updated dependencies [c1989f8] 29 | - @neo4j-cypher/svelte-codemirror@1.0.2 30 | 31 | ## 1.0.1 32 | 33 | ### Patch Changes 34 | 35 | - Updated dependencies [9379a74] 36 | - @neo4j-cypher/svelte-codemirror@1.0.1 37 | 38 | ## 1.0.0 39 | 40 | ### Major Changes 41 | 42 | - 13f7151: Initial pre-release 43 | 44 | ### Patch Changes 45 | 46 | - 4af77ae: Drop the styled component version due to technical compatibility and tooling limitations. Manually import CSS file to get a styled editor. 47 | - 896eddf: add missing @babel/runtime dependency 48 | - 8ba2deb: Exit pre-release mode 49 | - 1500721: Fix meta query - the last one didn't work with Neo4j 5.2 50 | - de33476: Add indentWithTab prop / option 51 | - 37252c7: Format Cypher results nicely in the Svelte demo app 52 | - 543e2bb: Add npm upload command to publish to surge 53 | - cec110d: Styling fixes and copy action on results 54 | - 8549a61: Apply workaround for node 18.14.0 support 55 | - 48363de: add antlr4-browser package (remove fs dependency) 56 | - 1500721: Bump deps to use Vite 4 57 | - 45a590b: Change license from GPL-3.0 to Apache-2.0 58 | - 543e2bb: Wrap lines in editor + result headers on svelte-ts 59 | - Updated dependencies [4af77ae] 60 | - Updated dependencies [896eddf] 61 | - Updated dependencies [8ba2deb] 62 | - Updated dependencies [6dcf015] 63 | - Updated dependencies [b35f29a] 64 | - Updated dependencies [b5ca4c5] 65 | - Updated dependencies [4a8e102] 66 | - Updated dependencies [de33476] 67 | - Updated dependencies [0a21042] 68 | - Updated dependencies [95e70e0] 69 | - Updated dependencies [8549a61] 70 | - Updated dependencies [42dc131] 71 | - Updated dependencies [1982d54] 72 | - Updated dependencies [95e6d25] 73 | - Updated dependencies [48363de] 74 | - Updated dependencies [77cb7d3] 75 | - Updated dependencies [acd35e1] 76 | - Updated dependencies [1d97f58] 77 | - Updated dependencies [45a590b] 78 | - Updated dependencies [91cb80a] 79 | - Updated dependencies [13f7151] 80 | - @neo4j-cypher/svelte-codemirror@1.0.0 81 | 82 | ## 1.0.0-next.26 83 | 84 | ### Patch Changes 85 | 86 | - 8549a61: Apply workaround for node 18.14.0 support 87 | - Updated dependencies [8549a61] 88 | - @neo4j-cypher/svelte-codemirror@1.0.0-next.26 89 | 90 | ## 1.0.0-next.25 91 | 92 | ### Patch Changes 93 | 94 | - 45a590b: Change license from GPL-3.0 to Apache-2.0 95 | - Updated dependencies [acd35e1] 96 | - Updated dependencies [45a590b] 97 | - @neo4j-cypher/svelte-codemirror@1.0.0-next.25 98 | 99 | ## 1.0.0-next.24 100 | 101 | ### Patch Changes 102 | 103 | - Updated dependencies [1d97f58] 104 | - @neo4j-cypher/svelte-codemirror@1.0.0-next.24 105 | 106 | ## 1.0.0-next.23 107 | 108 | ### Patch Changes 109 | 110 | - Updated dependencies [91cb80a] 111 | - @neo4j-cypher/svelte-codemirror@1.0.0-next.23 112 | 113 | ## 1.0.0-next.22 114 | 115 | ### Patch Changes 116 | 117 | - 543e2bb: Add npm upload command to publish to surge 118 | - 543e2bb: Wrap lines in editor + result headers on svelte-ts 119 | - @neo4j-cypher/svelte-codemirror@1.0.0-next.22 120 | 121 | ## 1.0.0-next.21 122 | 123 | ### Patch Changes 124 | 125 | - @neo4j-cypher/svelte-codemirror@1.0.0-next.21 126 | 127 | ## 1.0.0-next.20 128 | 129 | ### Patch Changes 130 | 131 | - 37252c7: Format Cypher results nicely in the Svelte demo app 132 | - cec110d: Styling fixes and copy action on results 133 | - @neo4j-cypher/svelte-codemirror@1.0.0-next.20 134 | 135 | ## 1.0.0-next.19 136 | 137 | ### Patch Changes 138 | 139 | - @neo4j-cypher/svelte-codemirror@1.0.0-next.19 140 | 141 | ## 1.0.0-next.18 142 | 143 | ### Patch Changes 144 | 145 | - @neo4j-cypher/svelte-codemirror@1.0.0-next.18 146 | 147 | ## 1.0.0-next.17 148 | 149 | ### Patch Changes 150 | 151 | - @neo4j-cypher/svelte-codemirror@1.0.0-next.17 152 | 153 | ## 1.0.0-next.16 154 | 155 | ### Patch Changes 156 | 157 | - Updated dependencies [77cb7d3] 158 | - @neo4j-cypher/svelte-codemirror@1.0.0-next.16 159 | 160 | ## 1.0.0-next.15 161 | 162 | ### Patch Changes 163 | 164 | - 1500721: Fix meta query - the last one didn't work with Neo4j 5.2 165 | - 1500721: Bump deps to use Vite 4 166 | - Updated dependencies [0a21042] 167 | - @neo4j-cypher/svelte-codemirror@1.0.0-next.15 168 | 169 | ## 1.0.0-next.14 170 | 171 | ### Patch Changes 172 | 173 | - Updated dependencies [95e6d25] 174 | - @neo4j-cypher/svelte-codemirror@1.0.0-next.14 175 | 176 | ## 1.0.0-next.13 177 | 178 | ### Patch Changes 179 | 180 | - Updated dependencies [42dc131] 181 | - @neo4j-cypher/svelte-codemirror@1.0.0-next.13 182 | 183 | ## 1.0.0-next.12 184 | 185 | ### Patch Changes 186 | 187 | - Updated dependencies [4a8e102] 188 | - @neo4j-cypher/svelte-codemirror@1.0.0-next.12 189 | 190 | ## 1.0.0-next.11 191 | 192 | ### Patch Changes 193 | 194 | - Updated dependencies [b5ca4c5] 195 | - @neo4j-cypher/svelte-codemirror@1.0.0-next.11 196 | 197 | ## 1.0.0-next.10 198 | 199 | ### Patch Changes 200 | 201 | - Updated dependencies [95e70e0] 202 | - @neo4j-cypher/svelte-codemirror@1.0.0-next.10 203 | 204 | ## 1.0.0-next.9 205 | 206 | ### Patch Changes 207 | 208 | - @neo4j-cypher/svelte-codemirror@1.0.0-next.9 209 | 210 | ## 1.0.0-next.8 211 | 212 | ### Patch Changes 213 | 214 | - @neo4j-cypher/svelte-codemirror@1.0.0-next.8 215 | 216 | ## 1.0.0-next.7 217 | 218 | ### Patch Changes 219 | 220 | - de33476: Add indentWithTab prop / option 221 | - Updated dependencies [de33476] 222 | - @neo4j-cypher/svelte-codemirror@1.0.0-next.7 223 | 224 | ## 1.0.0-next.6 225 | 226 | ### Patch Changes 227 | 228 | - @neo4j-cypher/svelte-codemirror@1.0.0-next.6 229 | 230 | ## 1.0.0-next.5 231 | 232 | ### Patch Changes 233 | 234 | - 4af77ae: Drop the styled component version due to technical compatibility and tooling limitations. Manually import CSS file to get a styled editor. 235 | - Updated dependencies [4af77ae] 236 | - @neo4j-cypher/svelte-codemirror@1.0.0-next.5 237 | 238 | ## 1.0.0-next.4 239 | 240 | ### Patch Changes 241 | 242 | - 48363de: add antlr4-browser package (remove fs dependency) 243 | - Updated dependencies [48363de] 244 | - @neo4j-cypher/svelte-codemirror@1.0.0-next.4 245 | 246 | ## 1.0.0-next.3 247 | 248 | ### Patch Changes 249 | 250 | - Updated dependencies [b35f29a] 251 | - @neo4j-cypher/svelte-codemirror@1.0.0-next.3 252 | 253 | ## 1.0.0-next.2 254 | 255 | ### Patch Changes 256 | 257 | - Updated dependencies [6dcf015] 258 | - Updated dependencies [1982d54] 259 | - @neo4j-cypher/svelte-codemirror@1.0.0-next.2 260 | 261 | ## 1.0.0-next.1 262 | 263 | ### Patch Changes 264 | 265 | - 896eddf: add missing @babel/runtime dependency 266 | - Updated dependencies [896eddf] 267 | - @neo4j-cypher/svelte-codemirror@1.0.0-next.1 268 | 269 | ## 1.0.0-next.0 270 | 271 | ### Major Changes 272 | 273 | - 13f7151: Initial pre-release 274 | 275 | ### Patch Changes 276 | 277 | - Updated dependencies [13f7151] 278 | - @neo4j-cypher/svelte-codemirror@1.0.0-next.0 279 | -------------------------------------------------------------------------------- /apps/svelte-ts/README.md: -------------------------------------------------------------------------------- 1 | ## Online Editor App using Svelte 2 | 3 | ### Features 4 | 5 | - Connects to `neo4j://localhost:7687` using `neo4j/password` 6 | - Editor with linted Cypher 7 | - Execute Cypher with cmd/ctrl + enter 8 | - Step in history with cmd/ctrl + up/down arrows 9 | - Updates auto complete schema with db labels and relationship types automatically 10 | 11 | ### Try it out locally 12 | 13 | ```bash 14 | npm install 15 | ``` 16 | 17 | ```bash 18 | npm run dev 19 | ``` 20 | -------------------------------------------------------------------------------- /apps/svelte-ts/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Vite + Svelte + TS + CypherEditor 7 | 8 | 9 |
10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /apps/svelte-ts/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "svelte-ts", 3 | "private": true, 4 | "version": "1.0.5", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite --port 5273", 8 | "deploy": "vite build", 9 | "upload": "npm run deploy && surge dist $([ -f .env ] && grep CNAME .env | awk -F '=' '{print $2}' || true)", 10 | "preview": "vite preview --port 5273", 11 | "check": "svelte-check --tsconfig ./tsconfig.json" 12 | }, 13 | "dependencies": { 14 | "@neo4j-cypher/svelte-codemirror": "1.0.5", 15 | "neo4j-driver": "^5.3.0" 16 | }, 17 | "devDependencies": { 18 | "@sveltejs/vite-plugin-svelte": "^2.0.2", 19 | "@tsconfig/svelte": "^3.0.0", 20 | "svelte": "^3.53.1", 21 | "svelte-check": "^2.10.0", 22 | "svelte-preprocess": "^5.0.0", 23 | "tslib": "^2.4.1", 24 | "typescript": "^4.9.3", 25 | "vite": "^4.0.2" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /apps/svelte-ts/src/ConnectModal.svelte: -------------------------------------------------------------------------------- 1 | 80 | 81 | 82 |

Connect to Neo4j

83 |
84 | 93 |
94 | 98 | 106 |
107 | {#if error.length} 108 |
109 | {error} 110 |
111 | {/if} 112 |
113 | 114 | 115 |
116 |
117 |
118 | 119 | 219 | -------------------------------------------------------------------------------- /apps/svelte-ts/src/CopyIcon.svelte: -------------------------------------------------------------------------------- 1 | 23 | -------------------------------------------------------------------------------- /apps/svelte-ts/src/command.utils.ts: -------------------------------------------------------------------------------- 1 | import type { GenericResult } from "./frames/Generic.types"; 2 | 3 | type Commands = { 4 | [key: string]: Command; 5 | }; 6 | type Command = { 7 | name: string; 8 | match: (input: string) => boolean; 9 | exec: () => GenericResult; 10 | }; 11 | 12 | export const commands: Commands = { 13 | HELP: { 14 | name: ":help", 15 | match: (input: string) => input === ":help", 16 | exec: () => ({ 17 | data: "- Cmd / Ctrl + Enter to run command or query\n- Cmd / Ctrl + Up / Down to step in history" 18 | }) 19 | } 20 | }; 21 | export const consoleCommands = Object.keys(commands).map((c) => ({ 22 | name: commands[c].name 23 | })); 24 | 25 | export function runCommand(cmd: string): Promise { 26 | const c = cmd.trim(); 27 | for (let command in commands) { 28 | const checkCommand = commands[command]; 29 | if (checkCommand.match(c)) { 30 | return new Promise((res) => res(checkCommand.exec())); 31 | } 32 | } 33 | } 34 | 35 | export function isCommand(str: string) { 36 | return str.startsWith(":"); 37 | } 38 | -------------------------------------------------------------------------------- /apps/svelte-ts/src/cypher.utils.ts: -------------------------------------------------------------------------------- 1 | import neo4j, { type Driver, type QueryResult } from "neo4j-driver"; 2 | 3 | export const schemaQuery = ` 4 | CALL db.labels() YIELD label 5 | WITH collect(label) AS labels 6 | RETURN labels AS result 7 | UNION ALL 8 | CALL db.relationshipTypes() YIELD relationshipType 9 | WITH collect(relationshipType) AS relationshipTypes 10 | RETURN relationshipTypes as result 11 | `; 12 | 13 | export function runQuery(driver: Driver, q: string): Promise { 14 | return new Promise(async (resolve, reject) => { 15 | if (!driver) { 16 | reject(new Error("Driver not connected")); 17 | return; 18 | } 19 | const session = driver.session(); 20 | try { 21 | const res = await session.run(q); 22 | resolve(res); 23 | } catch (e) { 24 | reject(e); 25 | } 26 | session.close(); 27 | }); 28 | } 29 | 30 | export async function connect({ 31 | connectURL, 32 | username, 33 | password 34 | }): Promise { 35 | const newDriver = neo4j.driver( 36 | connectURL, 37 | neo4j.auth.basic(username, password) 38 | ); 39 | await newDriver.verifyConnectivity(); 40 | return newDriver; 41 | } 42 | -------------------------------------------------------------------------------- /apps/svelte-ts/src/frames/Cypher.svelte: -------------------------------------------------------------------------------- 1 | 59 | 60 | 61 | 63 | {#each recordObjs.keys as key} 64 | 67 | {/each} 68 | 70 | 71 | {#each recordObjs.rows as row} 72 | 73 | {#each row as col} 74 | 80 | {/each} 81 | 82 | {/each} 83 | 84 |
65 | {key} 66 |
{col}
76 |
85 | 86 | 138 | -------------------------------------------------------------------------------- /apps/svelte-ts/src/frames/Generic.svelte: -------------------------------------------------------------------------------- 1 | 5 | 6 |

{result.data}

7 | 8 | 17 | -------------------------------------------------------------------------------- /apps/svelte-ts/src/frames/Generic.types.ts: -------------------------------------------------------------------------------- 1 | export type GenericResult = { 2 | data: string; 3 | }; 4 | -------------------------------------------------------------------------------- /apps/svelte-ts/src/history.store.ts: -------------------------------------------------------------------------------- 1 | import { get, writable } from "svelte/store"; 2 | 3 | type HistoryStoreEvents = 4 | | "PUSH_CURRENT" 5 | | "STEP_BACK" 6 | | "STEP_FORWARD" 7 | | "SET_CURRENT"; 8 | type EventPayload = string; 9 | 10 | export function historyStore(initValue: string = "", stackSize: number = 20) { 11 | let stackIndex: number | null = null; 12 | let stack = []; 13 | let editBuffer = ""; 14 | 15 | const store = writable(initValue); 16 | 17 | const send = (event: HistoryStoreEvents, payload?: EventPayload): void => { 18 | switch (event) { 19 | case "PUSH_CURRENT": 20 | stack.push(get(store)); 21 | stack = stack.slice(-1 * stackSize); 22 | stackIndex = null; 23 | store.set(""); 24 | break; 25 | case "STEP_BACK": 26 | if (stackIndex === null && stack.length) { 27 | editBuffer = get(store); 28 | stackIndex = stack.length; 29 | } 30 | if (stackIndex > 0) { 31 | stackIndex--; 32 | store.set(stack[stackIndex]); 33 | } 34 | break; 35 | case "STEP_FORWARD": 36 | if (stackIndex < stack.length - 1 && stackIndex !== null) { 37 | stackIndex++; 38 | store.set(stack[stackIndex]); 39 | } else if (stackIndex === stack.length - 1) { 40 | stackIndex = null; 41 | store.set(editBuffer); 42 | } 43 | break; 44 | case "SET_CURRENT": 45 | store.set(payload); 46 | stackIndex = null; 47 | break; 48 | default: 49 | break; 50 | } 51 | }; 52 | 53 | return { subscribe: store.subscribe, set: store.set, send }; 54 | } 55 | -------------------------------------------------------------------------------- /apps/svelte-ts/src/main.ts: -------------------------------------------------------------------------------- 1 | import "./style.css"; 2 | import App from "./App.svelte"; 3 | 4 | const app = new App({ 5 | target: document.getElementById("app") 6 | }); 7 | 8 | export default app; 9 | -------------------------------------------------------------------------------- /apps/svelte-ts/src/style.css: -------------------------------------------------------------------------------- 1 | *, 2 | :before, 3 | :after { 4 | box-sizing: border-box; 5 | } 6 | 7 | html { 8 | font-size: 16px; 9 | font-family: sans-serif; 10 | } 11 | 12 | body { 13 | background-color: #f6f7fa; 14 | margin: 0; 15 | padding: 0; 16 | } 17 | 18 | :root { 19 | --colors-neutral-90: rgb(21, 30, 41); 20 | --text-primary-50: rgb(0 111 214); 21 | --form-label-text-color: rgb(83, 91, 102); 22 | --border-color: rgb(196 200 205); 23 | --font-weight-bold: 700; 24 | --font-size-h6: 1rem; 25 | } 26 | 27 | h3 { 28 | font-size: 1.875rem; 29 | font-weight: var(--font-weight-bold); 30 | color: var(--colors-neutral-90); 31 | } 32 | -------------------------------------------------------------------------------- /apps/svelte-ts/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | interface ImportMetaEnv { 4 | readonly VITE_NEO4J_PASSWORD: string; 5 | readonly VITE_NEO4J_USERNAME: string; 6 | // more env variables... 7 | } 8 | 9 | interface ImportMeta { 10 | readonly env: ImportMetaEnv; 11 | } 12 | -------------------------------------------------------------------------------- /apps/svelte-ts/svelte.config.js: -------------------------------------------------------------------------------- 1 | import sveltePreprocess from "svelte-preprocess"; 2 | 3 | export default { 4 | // Consult https://github.com/sveltejs/svelte-preprocess 5 | // for more information about preprocessors 6 | preprocess: sveltePreprocess() 7 | }; 8 | -------------------------------------------------------------------------------- /apps/svelte-ts/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@tsconfig/svelte/tsconfig.json", 3 | "compilerOptions": { 4 | "target": "ESNext", 5 | "useDefineForClassFields": true, 6 | "module": "ESNext", 7 | "resolveJsonModule": true, 8 | "baseUrl": ".", 9 | /** 10 | * Typecheck JS in `.svelte` and `.js` files by default. 11 | * Disable checkJs if you'd like to use dynamic types in JS. 12 | * Note that setting allowJs false does not prevent the use 13 | * of JS in `.svelte` files. 14 | */ 15 | "allowJs": true, 16 | "checkJs": true, 17 | "isolatedModules": true 18 | }, 19 | "include": ["src/**/*.d.ts", "src/**/*.ts", "src/**/*.js", "src/**/*.svelte"], 20 | "references": [{ "path": "./tsconfig.node.json" }] 21 | } 22 | -------------------------------------------------------------------------------- /apps/svelte-ts/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "module": "ESNext", 5 | "moduleResolution": "Node" 6 | }, 7 | "include": ["vite.config.ts"] 8 | } 9 | -------------------------------------------------------------------------------- /apps/svelte-ts/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "vite"; 2 | import { svelte } from "@sveltejs/vite-plugin-svelte"; 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | plugins: [svelte()] 7 | }); 8 | -------------------------------------------------------------------------------- /babel.antlr4-browser.config.js: -------------------------------------------------------------------------------- 1 | const es = !!process.env.ES; 2 | const path = require("path"); 3 | 4 | module.exports = { 5 | presets: [ 6 | [ 7 | "@babel/preset-env", 8 | { 9 | // useBuiltIns: false, 10 | modules: es ? false : "commonjs", 11 | targets: { 12 | browsers: [ 13 | // 'last 2 versions', 14 | // 'not ie > 0', 15 | "chrome > 60" 16 | ] 17 | } 18 | // "targets": "> 0.25%, not dead" 19 | // "targets": "last 2 versions, > 5%" 20 | } 21 | ] 22 | ], 23 | plugins: [ 24 | "@babel/plugin-proposal-class-properties", 25 | "@babel/plugin-proposal-object-rest-spread", 26 | "@babel/plugin-transform-runtime", 27 | [ 28 | "babel-plugin-filter-imports", 29 | { 30 | imports: { fs: ["*"] }, 31 | keepImports: false 32 | } 33 | ] 34 | ] 35 | }; 36 | -------------------------------------------------------------------------------- /babel.antlr4.config.js: -------------------------------------------------------------------------------- 1 | const es = !!process.env.ES; 2 | const path = require("path"); 3 | 4 | module.exports = { 5 | presets: [ 6 | [ 7 | "@babel/preset-env", 8 | { 9 | // useBuiltIns: false, 10 | modules: es ? false : "commonjs", 11 | targets: { 12 | browsers: [ 13 | // 'last 2 versions', 14 | // 'not ie > 0', 15 | "chrome > 60" 16 | ] 17 | } 18 | // "targets": "> 0.25%, not dead" 19 | // "targets": "last 2 versions, > 5%" 20 | } 21 | ] 22 | ], 23 | plugins: [ 24 | "@babel/plugin-proposal-class-properties", 25 | "@babel/plugin-proposal-object-rest-spread", 26 | "@babel/plugin-transform-runtime", 27 | [ 28 | "babel-plugin-replace-imports", 29 | { 30 | test: /^antlr4$/, 31 | replacer: "@neo4j-cypher/antlr4-browser" 32 | } 33 | ] 34 | ] 35 | }; 36 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | const es = !!process.env.ES; 2 | const path = require("path"); 3 | 4 | module.exports = { 5 | presets: [ 6 | [ 7 | "@babel/preset-env", 8 | { 9 | // useBuiltIns: false, 10 | modules: es ? false : "commonjs", 11 | targets: { 12 | browsers: [ 13 | // 'last 2 versions', 14 | // 'not ie > 0', 15 | "chrome > 60" 16 | ] 17 | } 18 | // "targets": "> 0.25%, not dead" 19 | // "targets": "last 2 versions, > 5%" 20 | } 21 | ] 22 | ], 23 | plugins: [ 24 | "@babel/plugin-proposal-class-properties", 25 | "@babel/plugin-proposal-object-rest-spread", 26 | "@babel/plugin-transform-runtime" 27 | ] 28 | }; 29 | -------------------------------------------------------------------------------- /babel.es6.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | [ 4 | "@babel/preset-env", 5 | { 6 | // useBuiltIns: false, 7 | modules: false, 8 | targets: { 9 | browsers: [ 10 | // 'last 2 versions', 11 | // 'not ie > 0', 12 | "chrome > 60" 13 | ] 14 | } 15 | // "targets": "> 0.25%, not dead" 16 | // "targets": "last 2 versions, > 5%" 17 | } 18 | ] 19 | ], 20 | plugins: [ 21 | "@babel/plugin-proposal-class-properties", 22 | "@babel/plugin-proposal-object-rest-spread", 23 | "@babel/plugin-transform-runtime" 24 | ] 25 | }; 26 | -------------------------------------------------------------------------------- /babel.react.config.js: -------------------------------------------------------------------------------- 1 | const es = !!process.env.ES; 2 | const path = require("path"); 3 | 4 | module.exports = { 5 | presets: [ 6 | [ 7 | "@babel/preset-env", 8 | { 9 | // useBuiltIns: false, 10 | modules: es ? false : "commonjs", 11 | targets: { 12 | browsers: [ 13 | // 'last 2 versions', 14 | // 'not ie > 0', 15 | "chrome > 60" 16 | ] 17 | } 18 | // "targets": "> 0.25%, not dead" 19 | // "targets": "last 2 versions, > 5%" 20 | } 21 | ] 22 | ], 23 | plugins: [ 24 | "@babel/plugin-proposal-class-properties", 25 | "@babel/plugin-proposal-object-rest-spread", 26 | "@babel/plugin-transform-react-display-name", 27 | ["@babel/plugin-transform-react-jsx", { runtime: "automatic" }], 28 | "@babel/plugin-transform-runtime" 29 | ] 30 | }; 31 | -------------------------------------------------------------------------------- /demos/demo-base-react/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # demo-base-react 2 | 3 | ## 1.0.0 4 | 5 | ### Major Changes 6 | 7 | - 13f7151: Initial pre-release 8 | 9 | ### Patch Changes 10 | 11 | - 896eddf: add missing @babel/runtime dependency 12 | - 8ba2deb: Exit pre-release mode 13 | - de33476: Add indentWithTab prop / option 14 | - 0a21042: add bracketMatching & closeBrackets options (both default true) 15 | - 8549a61: Apply workaround for node 18.14.0 support 16 | - 42dc131: fix position/selection bug, add search & indentUnit options 17 | - 95e6d25: add cypherLanguage & various search/cursor options, misc improvements 18 | - 48363de: add antlr4-browser package (remove fs dependency) 19 | - acd35e1: Update repo url after move 20 | - 45a590b: Change license from GPL-3.0 to Apache-2.0 21 | - 91cb80a: Fix module exports + add shallow comparision on schema updates 22 | 23 | ## 1.0.0-next.9 24 | 25 | ### Patch Changes 26 | 27 | - 8549a61: Apply workaround for node 18.14.0 support 28 | 29 | ## 1.0.0-next.8 30 | 31 | ### Patch Changes 32 | 33 | - acd35e1: Update repo url after move 34 | - 45a590b: Change license from GPL-3.0 to Apache-2.0 35 | 36 | ## 1.0.0-next.7 37 | 38 | ### Patch Changes 39 | 40 | - 91cb80a: Fix module exports + add shallow comparision on schema updates 41 | 42 | ## 1.0.0-next.6 43 | 44 | ### Patch Changes 45 | 46 | - 0a21042: add bracketMatching & closeBrackets options (both default true) 47 | 48 | ## 1.0.0-next.5 49 | 50 | ### Patch Changes 51 | 52 | - 95e6d25: add cypherLanguage & various search/cursor options, misc improvements 53 | 54 | ## 1.0.0-next.4 55 | 56 | ### Patch Changes 57 | 58 | - 42dc131: fix position/selection bug, add search & indentUnit options 59 | 60 | ## 1.0.0-next.3 61 | 62 | ### Patch Changes 63 | 64 | - de33476: Add indentWithTab prop / option 65 | 66 | ## 1.0.0-next.2 67 | 68 | ### Patch Changes 69 | 70 | - 48363de: add antlr4-browser package (remove fs dependency) 71 | 72 | ## 1.0.0-next.1 73 | 74 | ### Patch Changes 75 | 76 | - 896eddf: add missing @babel/runtime dependency 77 | 78 | ## 1.0.0-next.0 79 | 80 | ### Major Changes 81 | 82 | - 13f7151: Initial pre-release 83 | -------------------------------------------------------------------------------- /demos/demo-base-react/README.md: -------------------------------------------------------------------------------- 1 | ### demo-base-react 2 | 3 | This package contains the svelte components used in react demos. 4 | -------------------------------------------------------------------------------- /demos/demo-base-react/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "demo-base-react", 3 | "description": "demo base react components", 4 | "private": true, 5 | "keywords": [], 6 | "version": "1.0.0", 7 | "author": "Neo4j Inc.", 8 | "license": "Apache-2.0", 9 | "main": "./lib/index.js", 10 | "module": "./es/index.js", 11 | "repository": { 12 | "type": "git", 13 | "url": "git://github.com/neo4j/cypher-editor.git" 14 | }, 15 | "bugs": { 16 | "url": "https://github.com/neo4j/cypher-editor/issues" 17 | }, 18 | "scripts": { 19 | "build-lib": "babel --config-file ../../babel.react.config.js --extensions \".js\" --out-dir lib ./src", 20 | "build-es": "cross-env ES=true babel --config-file ../../babel.react.config.js --extensions \".js\" --out-dir es ./src", 21 | "build": "npm run build-lib && npm run build-es", 22 | "clean:build": "rimraf lib && rimraf es" 23 | }, 24 | "files": [ 25 | "es/", 26 | "lib/", 27 | "README.md" 28 | ], 29 | "engineStrict": true, 30 | "engines": { 31 | "node": ">=16" 32 | }, 33 | "dependencies": { 34 | "@babel/runtime": "^7.20.13" 35 | }, 36 | "peerDependencies": { 37 | "react": ">=16" 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /demos/demo-base-react/src/App.js: -------------------------------------------------------------------------------- 1 | import React, { Fragment } from "react"; 2 | 3 | const App = (props) => { 4 | const { children } = props; 5 | 6 | return {children}; 7 | }; 8 | 9 | export default App; 10 | -------------------------------------------------------------------------------- /demos/demo-base-react/src/index.js: -------------------------------------------------------------------------------- 1 | export { default as App } from "./App"; 2 | export { default as Database } from "./Database"; 3 | -------------------------------------------------------------------------------- /demos/demo-base-svelte/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # demo-base-svelte 2 | 3 | ## 1.0.0 4 | 5 | ### Major Changes 6 | 7 | - 13f7151: Initial pre-release 8 | 9 | ### Patch Changes 10 | 11 | - 896eddf: add missing @babel/runtime dependency 12 | - 8ba2deb: Exit pre-release mode 13 | - de33476: Add indentWithTab prop / option 14 | - 0a21042: add bracketMatching & closeBrackets options (both default true) 15 | - 8549a61: Apply workaround for node 18.14.0 support 16 | - 42dc131: fix position/selection bug, add search & indentUnit options 17 | - 95e6d25: add cypherLanguage & various search/cursor options, misc improvements 18 | - 48363de: add antlr4-browser package (remove fs dependency) 19 | - acd35e1: Update repo url after move 20 | - 45a590b: Change license from GPL-3.0 to Apache-2.0 21 | - 91cb80a: Fix module exports + add shallow comparision on schema updates 22 | 23 | ## 1.0.0-next.9 24 | 25 | ### Patch Changes 26 | 27 | - 8549a61: Apply workaround for node 18.14.0 support 28 | 29 | ## 1.0.0-next.8 30 | 31 | ### Patch Changes 32 | 33 | - acd35e1: Update repo url after move 34 | - 45a590b: Change license from GPL-3.0 to Apache-2.0 35 | 36 | ## 1.0.0-next.7 37 | 38 | ### Patch Changes 39 | 40 | - 91cb80a: Fix module exports + add shallow comparision on schema updates 41 | 42 | ## 1.0.0-next.6 43 | 44 | ### Patch Changes 45 | 46 | - 0a21042: add bracketMatching & closeBrackets options (both default true) 47 | 48 | ## 1.0.0-next.5 49 | 50 | ### Patch Changes 51 | 52 | - 95e6d25: add cypherLanguage & various search/cursor options, misc improvements 53 | 54 | ## 1.0.0-next.4 55 | 56 | ### Patch Changes 57 | 58 | - 42dc131: fix position/selection bug, add search & indentUnit options 59 | 60 | ## 1.0.0-next.3 61 | 62 | ### Patch Changes 63 | 64 | - de33476: Add indentWithTab prop / option 65 | 66 | ## 1.0.0-next.2 67 | 68 | ### Patch Changes 69 | 70 | - 48363de: add antlr4-browser package (remove fs dependency) 71 | 72 | ## 1.0.0-next.1 73 | 74 | ### Patch Changes 75 | 76 | - 896eddf: add missing @babel/runtime dependency 77 | 78 | ## 1.0.0-next.0 79 | 80 | ### Major Changes 81 | 82 | - 13f7151: Initial pre-release 83 | -------------------------------------------------------------------------------- /demos/demo-base-svelte/README.md: -------------------------------------------------------------------------------- 1 | ### demo-base-svelte 2 | 3 | This package contains the svelte components used in svelte demos. 4 | -------------------------------------------------------------------------------- /demos/demo-base-svelte/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "demo-base-svelte", 3 | "description": "demo base svelte components", 4 | "private": true, 5 | "keywords": [], 6 | "version": "1.0.0", 7 | "author": "Neo4j Inc.", 8 | "license": "Apache-2.0", 9 | "svelte": "src/index.js", 10 | "repository": { 11 | "type": "git", 12 | "url": "git://github.com/neo4j/cypher-editor.git" 13 | }, 14 | "bugs": { 15 | "url": "https://github.com/neo4j/cypher-editor/issues" 16 | }, 17 | "files": [ 18 | "src/", 19 | "README.md" 20 | ], 21 | "engineStrict": true, 22 | "engines": { 23 | "node": ">=16" 24 | }, 25 | "peerDependencies": { 26 | "svelte": "^3.49.0" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /demos/demo-base-svelte/src/App.svelte: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /demos/demo-base-svelte/src/index.js: -------------------------------------------------------------------------------- 1 | export { default as App } from "./App.svelte"; 2 | export { default as Database } from "./Database.svelte"; 3 | -------------------------------------------------------------------------------- /demos/demo-base/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # demo-base 2 | 3 | ## 1.0.0 4 | 5 | ### Major Changes 6 | 7 | - 13f7151: Initial pre-release 8 | 9 | ### Patch Changes 10 | 11 | - 896eddf: add missing @babel/runtime dependency 12 | - 8ba2deb: Exit pre-release mode 13 | - de33476: Add indentWithTab prop / option 14 | - 0a21042: add bracketMatching & closeBrackets options (both default true) 15 | - 8549a61: Apply workaround for node 18.14.0 support 16 | - 42dc131: fix position/selection bug, add search & indentUnit options 17 | - 95e6d25: add cypherLanguage & various search/cursor options, misc improvements 18 | - 48363de: add antlr4-browser package (remove fs dependency) 19 | - acd35e1: Update repo url after move 20 | - 45a590b: Change license from GPL-3.0 to Apache-2.0 21 | - 91cb80a: Fix module exports + add shallow comparision on schema updates 22 | 23 | ## 1.0.0-next.9 24 | 25 | ### Patch Changes 26 | 27 | - 8549a61: Apply workaround for node 18.14.0 support 28 | 29 | ## 1.0.0-next.8 30 | 31 | ### Patch Changes 32 | 33 | - acd35e1: Update repo url after move 34 | - 45a590b: Change license from GPL-3.0 to Apache-2.0 35 | 36 | ## 1.0.0-next.7 37 | 38 | ### Patch Changes 39 | 40 | - 91cb80a: Fix module exports + add shallow comparision on schema updates 41 | 42 | ## 1.0.0-next.6 43 | 44 | ### Patch Changes 45 | 46 | - 0a21042: add bracketMatching & closeBrackets options (both default true) 47 | 48 | ## 1.0.0-next.5 49 | 50 | ### Patch Changes 51 | 52 | - 95e6d25: add cypherLanguage & various search/cursor options, misc improvements 53 | 54 | ## 1.0.0-next.4 55 | 56 | ### Patch Changes 57 | 58 | - 42dc131: fix position/selection bug, add search & indentUnit options 59 | 60 | ## 1.0.0-next.3 61 | 62 | ### Patch Changes 63 | 64 | - de33476: Add indentWithTab prop / option 65 | 66 | ## 1.0.0-next.2 67 | 68 | ### Patch Changes 69 | 70 | - 48363de: add antlr4-browser package (remove fs dependency) 71 | 72 | ## 1.0.0-next.1 73 | 74 | ### Patch Changes 75 | 76 | - 896eddf: add missing @babel/runtime dependency 77 | 78 | ## 1.0.0-next.0 79 | 80 | ### Major Changes 81 | 82 | - 13f7151: Initial pre-release 83 | -------------------------------------------------------------------------------- /demos/demo-base/README.md: -------------------------------------------------------------------------------- 1 | ### demo-base 2 | 3 | This package contains values used across all demo packages. 4 | 5 | Interesting exports to change are: 6 | 7 | ``` 8 | export const longQuery = 'this is the initial query that will show up on first load'; 9 | export const initialPosition = { line: 2, column: 3 }; // go to this position on first load 10 | export const neo4jSchema = { /* this is an object you can define to control advanced autocompletion etc */ }; 11 | ``` 12 | -------------------------------------------------------------------------------- /demos/demo-base/css/app.css: -------------------------------------------------------------------------------- 1 | :root { 2 | font-family: Inter, Avenir, Helvetica, Arial, sans-serif; 3 | font-size: 16px; 4 | line-height: 24px; 5 | font-weight: 400; 6 | 7 | color-scheme: light dark; 8 | font-synthesis: none; 9 | text-rendering: optimizeLegibility; 10 | -webkit-font-smoothing: antialiased; 11 | -moz-osx-font-smoothing: grayscale; 12 | -webkit-text-size-adjust: 100%; 13 | 14 | /* dark theme */ 15 | color: rgba(255, 255, 255, 0.87); 16 | background-color: #242424; 17 | } 18 | 19 | body { 20 | margin: 0; 21 | display: flex; 22 | min-width: 320px; 23 | min-height: 100vh; 24 | width: 100%; 25 | min-width: 100%; 26 | max-width: 100%; 27 | overflow-x: hidden; 28 | } 29 | 30 | a { 31 | font-weight: 500; 32 | text-decoration: inherit; 33 | /* dark & light theme */ 34 | color: #646cff; 35 | } 36 | a:hover { 37 | /* dark theme */ 38 | color: #535bf2; 39 | } 40 | 41 | h1 { 42 | font-size: 3.2em; 43 | line-height: 1.1; 44 | } 45 | 46 | button { 47 | border-radius: 8px; 48 | border: 1px solid transparent; 49 | padding: 0.5em 1em; 50 | font-size: 0.8em; 51 | font-weight: 500; 52 | font-family: inherit; 53 | cursor: pointer; 54 | transition: border-color 0.25s; 55 | /* dark theme */ 56 | background-color: #1a1a1a; 57 | color: inherit; 58 | } 59 | button:hover { 60 | /* dark & light theme */ 61 | border-color: #646cff; 62 | } 63 | button:focus, 64 | button:focus-visible { 65 | outline: 4px auto -webkit-focus-ring-color; 66 | } 67 | .right button { 68 | font-size: 1em; 69 | padding: 0.6em 1.2em; 70 | } 71 | 72 | .setting-values button.setting-active { 73 | /* dark theme */ 74 | border: 1px solid white; 75 | } 76 | 77 | @media (prefers-color-scheme: light) { 78 | :root { 79 | color: #213547; 80 | background-color: #ffffff; 81 | } 82 | a:hover { 83 | color: #747bff; 84 | } 85 | button { 86 | background-color: #f9f9f9; 87 | } 88 | 89 | .setting-values button.setting-active { 90 | /* dark theme */ 91 | border: 1px solid black; 92 | } 93 | } 94 | 95 | #app { 96 | width: 100%; 97 | min-width: 100%; 98 | max-width: 100%; 99 | } 100 | 101 | .database { 102 | display: flex; 103 | flex: 1 1 auto; 104 | flex-direction: row; 105 | } 106 | 107 | .left { 108 | display: flex; 109 | flex-direction: column; 110 | min-width: 260px; 111 | max-width: 260px; 112 | width: 260px; 113 | font-size: 14px; 114 | padding: 0 8px; 115 | max-height: 100vh; 116 | overflow-y: auto; 117 | } 118 | 119 | .setting { 120 | display: flex; 121 | flex-direction: row; 122 | padding: 4px 0; 123 | } 124 | 125 | .setting.setting-long { 126 | flex-direction: column; 127 | margin: 0; 128 | } 129 | 130 | .setting-label { 131 | display: flex; 132 | font-size: 1.2em; 133 | padding: 4px 0; 134 | align-items: center; 135 | } 136 | 137 | .setting-label button { 138 | margin: 4px; 139 | } 140 | 141 | .setting-label button:first-child { 142 | margin-left: 8px; 143 | } 144 | 145 | .setting-short .setting-label { 146 | min-width: 4em; 147 | } 148 | 149 | .setting-values { 150 | display: flex; 151 | margin: 0 4px; 152 | max-width: calc(100% - 8px); 153 | } 154 | 155 | .setting-long .setting-values { 156 | margin: 0; 157 | max-width: 100%; 158 | } 159 | 160 | .setting-values button { 161 | display: flex; 162 | flex: none; 163 | margin: 4px; 164 | border: 1px solid rgba(0, 0, 0, 0); 165 | } 166 | 167 | .setting-values label { 168 | align-self: center; 169 | } 170 | 171 | .setting-values input { 172 | display: flex; 173 | flex: 1 1 auto; 174 | margin: 5px; 175 | padding: 1px 5px; 176 | max-width: 4em; 177 | } 178 | 179 | .setting-values input.short-input { 180 | max-width: 3em; 181 | } 182 | 183 | .right { 184 | display: flex; 185 | flex: 1 1 auto; 186 | flex-direction: column; 187 | padding-right: 8px; 188 | max-width: calc(100% - 276px); 189 | } 190 | 191 | .card { 192 | display: flex; 193 | width: 100%; 194 | min-width: 100%; 195 | max-width: 100%; 196 | padding: 4px; 197 | } 198 | 199 | .card h1 { 200 | padding-right: 16px; 201 | } 202 | 203 | .database-editor { 204 | display: flex; 205 | width: calc(100% - 16px); 206 | min-width: calc(100% - 16px); 207 | max-width: calc(100% - 16px); 208 | } 209 | 210 | .info { 211 | display: flex; 212 | width: 100%; 213 | min-width: 100%; 214 | max-width: 100%; 215 | flex-direction: row; 216 | } 217 | 218 | .card .info { 219 | width: calc(100% - 16px); 220 | min-width: calc(100% - 16px); 221 | max-width: calc(100% - 16px); 222 | } 223 | 224 | .info-item-long { 225 | display: flex; 226 | width: 40%; 227 | } 228 | 229 | .info-item { 230 | display: flex; 231 | width: 20%; 232 | } 233 | 234 | .logs { 235 | display: flex; 236 | width: calc(100% - 16px); 237 | flex-direction: column; 238 | } 239 | 240 | .logs-header { 241 | display: flex; 242 | flex-direction: row; 243 | padding: 4px 0; 244 | } 245 | 246 | .logs-header h3 { 247 | margin: 0; 248 | } 249 | 250 | .right .logs-header button { 251 | margin: 0 16px; 252 | padding: 0.3em 0.6em; 253 | font-size: 0.8em; 254 | line-height: 1; 255 | } 256 | 257 | .logs-filters { 258 | display: flex; 259 | flex-direction: row; 260 | padding: 4px 0; 261 | } 262 | 263 | .logs-filter { 264 | display: flex; 265 | flex-direction: row; 266 | padding: 0 4px; 267 | } 268 | 269 | .logs-filter input { 270 | margin-left: 8px; 271 | margin-right: 20px; 272 | } 273 | 274 | .logs textarea { 275 | min-height: 5em; 276 | } 277 | 278 | /* this next rule sets the editor size for codemirror 5 */ 279 | 280 | .CodeMirror.cm-s-cypher { 281 | min-width: 100%; 282 | height: 300px; 283 | } 284 | 285 | /* this next rule sets the editor size for codemirror 6 */ 286 | 287 | .cm-editor { 288 | min-width: 100%; 289 | height: 300px; 290 | } 291 | -------------------------------------------------------------------------------- /demos/demo-base/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "demo-base", 3 | "private": true, 4 | "description": "demo base files for cypher editor", 5 | "keywords": [], 6 | "version": "1.0.0", 7 | "author": "Neo4j Inc.", 8 | "license": "Apache-2.0", 9 | "main": "./lib/index.js", 10 | "module": "./es/index.js", 11 | "repository": { 12 | "type": "git", 13 | "url": "git://github.com/neo4j/cypher-editor.git" 14 | }, 15 | "bugs": { 16 | "url": "https://github.com/neo4j/cypher-editor/issues" 17 | }, 18 | "scripts": { 19 | "build-lib": "babel --config-file ../../babel.config.js --extensions \".js\" --out-dir lib ./src", 20 | "build-es": "cross-env ES=true babel --config-file ../../babel.config.js --extensions \".js\" --out-dir es ./src", 21 | "build": "npm run build-lib && npm run build-es", 22 | "clean:build": "rimraf lib && rimraf es" 23 | }, 24 | "files": [ 25 | "css/", 26 | "es/", 27 | "lib/", 28 | "README.md" 29 | ], 30 | "engineStrict": true, 31 | "engines": { 32 | "node": ">=16" 33 | }, 34 | "dependencies": { 35 | "@babel/runtime": "^7.20.13", 36 | "neo4j-driver": "^5.5.0" 37 | }, 38 | "devDependencies": { 39 | "@babel/cli": "^7.20.7", 40 | "@babel/core": "^7.20.12", 41 | "@babel/plugin-proposal-class-properties": "^7.18.6", 42 | "@babel/plugin-proposal-object-rest-spread": "^7.20.7", 43 | "@babel/plugin-transform-regenerator": "^7.20.5", 44 | "@babel/plugin-transform-runtime": "^7.19.6", 45 | "@babel/preset-env": "^7.20.2" 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /demos/demo-codemirror-6-vite-svelte/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | cm-6-vite-svelte 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /demos/demo-codemirror-6-vite-svelte/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "demo-codemirror-6-vite-svelte", 3 | "private": true, 4 | "version": "1.0.5", 5 | "type": "module", 6 | "scripts": { 7 | "start": "vite --port 5175", 8 | "deploy": "vite build", 9 | "serve": "pm2 serve dist 5175 --spa --name demo5175", 10 | "unserve": "pm2 delete demo5175", 11 | "serve:bg": "npx -y http-server dist --port 5175", 12 | "e2e": "export PORT=5175; playwright test --config=../../playwright.config.js", 13 | "e2e:selector": "playwright codegen http://localhost:5175", 14 | "check": "svelte-check --tsconfig ./tsconfig.json" 15 | }, 16 | "dependencies": { 17 | "@codemirror/autocomplete": "^6.4.1", 18 | "@codemirror/commands": "^6.2.0", 19 | "@codemirror/language": "^6.6.0", 20 | "@codemirror/lint": "^6.1.0", 21 | "@codemirror/search": "^6.2.3", 22 | "@codemirror/state": "^6.2.0", 23 | "@codemirror/view": "^6.8.1", 24 | "@lezer/highlight": "^1.1.3", 25 | "@neo4j-cypher/codemirror": "1.0.3", 26 | "@neo4j-cypher/svelte-codemirror": "1.0.5", 27 | "demo-base": "1.0.0", 28 | "demo-base-svelte": "1.0.0", 29 | "neo4j-driver": "^5.5.0" 30 | }, 31 | "devDependencies": { 32 | "@sveltejs/vite-plugin-svelte": "^2.0.2", 33 | "@tsconfig/svelte": "^3.0.0", 34 | "svelte": "^3.55.1", 35 | "svelte-check": "^3.0.3", 36 | "svelte-preprocess": "^5.0.1", 37 | "tslib": "^2.5.0", 38 | "typescript": "^4.9.5", 39 | "vite": "^4.1.1" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /demos/demo-codemirror-6-vite-svelte/public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /demos/demo-codemirror-6-vite-svelte/src/App.svelte: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 14 | 15 | -------------------------------------------------------------------------------- /demos/demo-codemirror-6-vite-svelte/src/main.ts: -------------------------------------------------------------------------------- 1 | import "demo-base/css/app.css"; 2 | import "@neo4j-cypher/codemirror/css/cypher-codemirror.css"; 3 | import App from "./App.svelte"; 4 | 5 | const app = new App({ 6 | target: document.getElementById("app") 7 | }); 8 | 9 | export default app; 10 | -------------------------------------------------------------------------------- /demos/demo-codemirror-6-vite-svelte/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | -------------------------------------------------------------------------------- /demos/demo-codemirror-6-vite-svelte/svelte.config.js: -------------------------------------------------------------------------------- 1 | import sveltePreprocess from "svelte-preprocess"; 2 | 3 | export default { 4 | // Consult https://github.com/sveltejs/svelte-preprocess 5 | // for more information about preprocessors 6 | preprocess: sveltePreprocess() 7 | }; 8 | -------------------------------------------------------------------------------- /demos/demo-codemirror-6-vite-svelte/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@tsconfig/svelte/tsconfig.json", 3 | "compilerOptions": { 4 | "target": "ESNext", 5 | "useDefineForClassFields": true, 6 | "module": "ESNext", 7 | "resolveJsonModule": true, 8 | "baseUrl": ".", 9 | /** 10 | * Typecheck JS in `.svelte` and `.js` files by default. 11 | * Disable checkJs if you'd like to use dynamic types in JS. 12 | * Note that setting allowJs false does not prevent the use 13 | * of JS in `.svelte` files. 14 | */ 15 | "allowJs": true, 16 | "checkJs": true, 17 | // "isolatedModules": true, 18 | "jsx": "react" 19 | }, 20 | "include": ["src/**/*.d.ts", "src/**/*.ts", "src/**/*.js", "src/**/*.svelte"], 21 | "references": [{ "path": "./tsconfig.node.json" }] 22 | } 23 | -------------------------------------------------------------------------------- /demos/demo-codemirror-6-vite-svelte/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "module": "ESNext", 5 | "moduleResolution": "Node" 6 | }, 7 | "include": ["vite.config.ts"] 8 | } 9 | -------------------------------------------------------------------------------- /demos/demo-codemirror-6-vite-svelte/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "vite"; 2 | import { svelte } from "@sveltejs/vite-plugin-svelte"; 3 | 4 | import * as path from "path"; 5 | 6 | // const absPath = aPath => path.resolve(__dirname, aPath); 7 | 8 | // https://vitejs.dev/config/ 9 | export default defineConfig({ 10 | plugins: [svelte()], 11 | optimizeDeps: { 12 | exclude: ["cypher-codemirror", "cypher-antlr4", "cypher-editor-support"] 13 | }, 14 | resolve: { 15 | alias: { 16 | // 'cypher-codemirror/css/cypher-codemirror.css': absPath('../cypher-codemirror/css/cypher-codemirror.css'), 17 | // 'cypher-codemirror': absPath('../cypher-codemirror/src/index.js'), 18 | // 'cypher-antlr4': absPath('../cypher-antlr4/src/index.js'), 19 | // 'cypher-antlr4-simple': absPath('../cypher-antlr4-simple/src/index.js'), 20 | // 'cypher-editor-support': absPath('../cypher-editor-support/src/index.js'), 21 | // 'demo-base': absPath('../demo-base/src/index.js') 22 | 23 | "@neo4j-cypher/codemirror/css/cypher-codemirror.css": 24 | "@neo4j-cypher/codemirror/css/cypher-codemirror.css", 25 | "@neo4j-cypher/codemirror": "@neo4j-cypher/codemirror/src/codemirror.js", 26 | "@neo4j-cypher/antlr4": "@neo4j-cypher/antlr4/src/index.js", 27 | "@neo4j-cypher/antlr4-simple": "@neo4j-cypher/antlr4-simple/src/index.js", 28 | "@neo4j-cypher/editor-support": 29 | "@neo4j-cypher/editor-support/src/editor-support.js", 30 | "demo-base/css/app.css": "demo-base/css/app.css", 31 | "demo-base": "demo-base/src/index.js" 32 | } 33 | } 34 | }); 35 | -------------------------------------------------------------------------------- /demos/demo-codemirror-6-webpack-react/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "demo-codemirror-6-webpack-react", 3 | "private": true, 4 | "version": "1.0.4", 5 | "scripts": { 6 | "startNoLocal": "cross-env NODE_ENV=\"development\" webpack serve", 7 | "start": "cross-env NODE_ENV=\"development\" webpack serve --config ./webpack.local.config.js", 8 | "e2e": "export PORT=5176; playwright test --config=../../playwright.config.js", 9 | "e2e:selector": "playwright codegen http://localhost:5176", 10 | "deploy": "npm run clean:deploy && cross-env NODE_ENV=\"production\" webpack", 11 | "clean:deploy": "rimraf dist", 12 | "serve": "pm2 serve dist 5176 --spa --name demo5176", 13 | "unserve": "pm2 delete demo5176" 14 | }, 15 | "dependencies": { 16 | "@codemirror/autocomplete": "^6.3.4", 17 | "@codemirror/commands": "^6.1.2", 18 | "@codemirror/language": "^6.3.1", 19 | "@codemirror/lint": "^6.1.0", 20 | "@codemirror/search": "^6.2.3", 21 | "@codemirror/state": "^6.1.4", 22 | "@codemirror/view": "^6.6.0", 23 | "@lezer/highlight": "^1.1.3", 24 | "@neo4j-cypher/codemirror": "1.0.3", 25 | "@neo4j-cypher/react-codemirror": "1.0.4", 26 | "demo-base": "1.0.0", 27 | "demo-base-react": "1.0.0", 28 | "neo4j-driver": "5.3.0", 29 | "react": "^18.2.0", 30 | "react-dom": "^18.2.0" 31 | }, 32 | "devDependencies": { 33 | "babel-loader": "^9.1.0", 34 | "cross-env": "^7.0.3", 35 | "css-loader": "^6.7.2", 36 | "css-minimizer-webpack-plugin": "^4.2.2", 37 | "file-loader": "^6.2.0", 38 | "glob": "^8.0.3", 39 | "html-webpack-deploy-plugin": "^3.0.0", 40 | "html-webpack-plugin": "^5.5.0", 41 | "mini-css-extract-plugin": "^2.7.1", 42 | "style-loader": "^3.3.1", 43 | "terser-webpack-plugin": "^5.3.6", 44 | "tsconfig-paths-webpack-plugin": "^4.0.0", 45 | "tslib": "^2.4.1", 46 | "typescript": "^4.9.3", 47 | "url-loader": "^4.1.1", 48 | "webpack": "^5.75.0", 49 | "webpack-cli": "^5.0.0", 50 | "webpack-dev-server": "^4.11.1" 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /demos/demo-codemirror-6-webpack-react/src/App.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | import { App as AppBase, Database } from "demo-base-react"; 4 | import { CypherEditor } from "@neo4j-cypher/react-codemirror"; 5 | 6 | const App = () => { 7 | return ( 8 | 9 | 15 | 16 | ); 17 | }; 18 | 19 | export default App; 20 | -------------------------------------------------------------------------------- /demos/demo-codemirror-6-webpack-react/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | cm-6-webpack-react 8 | 9 | 10 |
11 | 12 | 13 | -------------------------------------------------------------------------------- /demos/demo-codemirror-6-webpack-react/src/main.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | // import { render } from "react-dom"; 3 | import { createRoot } from "react-dom/client"; 4 | 5 | import "demo-base/css/app.css"; 6 | import App from "./App"; 7 | 8 | // render(, document.getElementById("app")); 9 | const root = createRoot(document.getElementById("app")); 10 | root.render(); 11 | -------------------------------------------------------------------------------- /demos/demo-codemirror-6-webpack-react/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | const Webpack = require("webpack"); 3 | const HtmlWebpackPlugin = require("html-webpack-plugin"); 4 | const HtmlWebpackDeployPlugin = require("html-webpack-deploy-plugin"); 5 | const MiniCssExtractPlugin = require("mini-css-extract-plugin"); 6 | // const TsconfigPathsPlugin = require("tsconfig-paths-webpack-plugin"); 7 | 8 | const { NODE_ENV } = process.env; 9 | 10 | const mode = NODE_ENV; 11 | const isDev = mode !== "production"; 12 | 13 | const basePath = __dirname; 14 | const USE_STATIC = false; 15 | const publicPath = USE_STATIC ? "/static/" : "/"; 16 | 17 | const babelConfigPath = path.join(__dirname, "../../babel.react.config.js"); 18 | 19 | module.exports = { 20 | resolve: { 21 | alias: {}, 22 | modules: [ 23 | path.resolve(basePath, "node_modules"), 24 | path.resolve(basePath, "../../node_modules") 25 | ], 26 | extensions: [".js", ".jsx", ".ts", ".tsx", ".mjs"], 27 | // plugins: [new TsconfigPathsPlugin({ configFile: './tsconfig.json' })], 28 | mainFields: ["browser", "module", "main"] 29 | }, 30 | mode: NODE_ENV, 31 | entry: [path.join(basePath, "src/main.js")], 32 | output: { 33 | filename: "app-[hash].js", 34 | chunkFilename: "[name]-[hash].bundle.js", 35 | publicPath, 36 | path: USE_STATIC 37 | ? path.join(basePath, "dist/static") 38 | : path.join(basePath, "dist") 39 | }, 40 | plugins: [ 41 | new Webpack.DefinePlugin({ 42 | PUBLIC_PATH: JSON.stringify(publicPath) 43 | }), 44 | new MiniCssExtractPlugin({ 45 | filename: "[name].css", 46 | chunkFilename: "[id].css" 47 | }), 48 | new HtmlWebpackPlugin({ 49 | template: "src/index.html", 50 | path: "dist", 51 | filename: USE_STATIC ? "../index.html" : "index.html" 52 | // favicon: 'src/favicon.ico' 53 | }), 54 | new HtmlWebpackDeployPlugin({ 55 | addAssetsPath: (assetPath) => assetPath, 56 | assets: { 57 | copy: [{ from: "../../packages/codemirror/css", to: "css/" }], 58 | links: ["css/cypher-codemirror.css"] 59 | } 60 | }) 61 | ], 62 | module: { 63 | rules: [ 64 | { 65 | test: /\.(js|jsx|ts|tsx)$/, 66 | // "include" will fail the transpile 67 | // include: [path.join(basePath, 'src')], 68 | exclude: /node_modules/, 69 | loader: "babel-loader", 70 | options: { 71 | configFile: babelConfigPath 72 | } 73 | }, 74 | { 75 | test: /\.css$/, // global css files that don't need any processing 76 | // include: [path.join(basePath, 'src')], 77 | use: ["style-loader", "css-loader"] 78 | }, 79 | { 80 | test: /\.(png|gif|jpg|svg)$/, 81 | include: [path.join(basePath, "src")], 82 | use: "file-loader?limit=20480&name=assets/[name]-[hash].[ext]" 83 | }, 84 | { 85 | test: /\.woff$/, 86 | include: [path.join(basePath, "src")], 87 | use: "file-loader?limit=65000&mimetype=application/font-woff&name=assets/fonts/[name].[ext]" 88 | }, 89 | { 90 | test: /\.woff2$/, 91 | include: [path.join(basePath, "src")], 92 | use: "file-loader?limit=65000&mimetype=application/font-woff2&name=assets/fonts/[name].[ext]" 93 | }, 94 | { 95 | test: /\.[ot]tf$/, 96 | include: [path.join(basePath, "src")], 97 | use: "file-loader?limit=65000&mimetype=application/octet-stream&name=assets/fonts/[name].[ext]" 98 | }, 99 | { 100 | test: /\.eot$/, 101 | include: [path.join(basePath, "src")], 102 | use: "file-loader?limit=65000&mimetype=application/vnd.ms-fontobject&name=assets/fonts/[name].[ext]" 103 | } 104 | ] 105 | }, 106 | optimization: {}, 107 | // devtool: isDev ? 'cheap-module-source-map' : 'source-map', 108 | devtool: isDev ? "eval-source-map" : "source-map", 109 | devServer: { 110 | host: "0.0.0.0", 111 | port: 5176, 112 | historyApiFallback: USE_STATIC ? { index: "/static/../index.html" } : true 113 | } 114 | }; 115 | -------------------------------------------------------------------------------- /demos/demo-codemirror-6-webpack-react/webpack.local.config.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | const fs = require("fs"); 3 | 4 | const webpackConfig = require("./webpack.config"); 5 | 6 | const namedPackages = [ 7 | "@neo4j-cypher/codemirror", 8 | "@neo4j-cypher/editor-support", 9 | "@neo4j-cypher/react-codemirror" 10 | // "@neo4j-cypher/svelte-codemirror" 11 | ].map((name) => ({ name, type: "named" })); 12 | 13 | const indexPackages = [ 14 | "@neo4j-cypher/antlr4", 15 | "@neo4j-cypher/antlr4-simple", 16 | "@neo4j-cypher/extract-statements" 17 | ].map((name) => ({ name, type: "index" })); 18 | 19 | const demoPackages = [ 20 | "demo-base", 21 | "demo-base-react" 22 | // "demo-base-svelte" 23 | ].map((name) => ({ name, type: "demo" })); 24 | 25 | const allPackages = namedPackages.concat(indexPackages).concat(demoPackages); 26 | 27 | const localPackages = allPackages.reduce((lp, pkg) => { 28 | const { name, type } = pkg; 29 | const pathName = name.includes("/") 30 | ? name.substring(name.indexOf("/") + 1) 31 | : name; 32 | const basePath = type === "demo" ? "../" : "../../packages/"; 33 | lp[name] = { 34 | rootPath: basePath + pathName, 35 | entry: { 36 | srcPath: "src", 37 | entryFile: type === "named" ? pathName + ".js" : "index.js" 38 | } 39 | }; 40 | return lp; 41 | }, {}); 42 | 43 | const basePath = process.cwd(); 44 | const babelConfigPath = path.join(__dirname, "../../babel.react.config.js"); 45 | 46 | const modulePackages = [path.join(basePath, "../../node_modules")]; 47 | 48 | const description = "Local Packages Map"; 49 | const babelCacheDirectory = true; 50 | const sourceRegexp = /\.js?$/; 51 | 52 | const packageToEntryFileMap = {}; // spread into resolve alias 53 | const packageToSrcPathMap = {}; 54 | 55 | let stats; 56 | let foundSrcPath; 57 | let foundEntryFile; 58 | let allFound = true; 59 | 60 | for (let packageName of Object.keys(localPackages)) { 61 | const packageObject = localPackages[packageName]; 62 | 63 | const { rootPath, entry } = packageObject; 64 | if (entry !== undefined) { 65 | const { srcPath, entryFile } = entry; 66 | const localSrcPath = path.join(rootPath || "", srcPath || ""); 67 | const localEntryFile = path.join(localSrcPath, entryFile); 68 | try { 69 | foundSrcPath = path.resolve(basePath, localSrcPath); 70 | foundEntryFile = path.resolve(basePath, localEntryFile); 71 | stats = fs.statSync(foundEntryFile); 72 | if (stats.isDirectory() || stats.isFile()) { 73 | packageToEntryFileMap[packageName] = foundEntryFile; 74 | packageToSrcPathMap[packageName] = foundSrcPath; 75 | console.log( 76 | description + " - resource found: ", 77 | packageName, 78 | foundEntryFile 79 | ); 80 | } else { 81 | console.warn( 82 | description + " - resource was not a file or directory: ", 83 | packageName, 84 | localEntryFile 85 | ); 86 | allFound = false; 87 | } 88 | } catch (error) { 89 | console.warn( 90 | description + " - error loading resource: ", 91 | packageName, 92 | localEntryFile 93 | ); 94 | allFound = false; 95 | } 96 | } 97 | } 98 | if (!allFound) { 99 | console.warn( 100 | description + " - base path for the above errors was: ", 101 | basePath 102 | ); 103 | process.exit(1); 104 | } 105 | 106 | let resolve = webpackConfig.resolve || {}; 107 | 108 | const extraAlias = { 109 | "@neo4j-cypher/codemirror/css/cypher-codemirror.css": path.resolve( 110 | basePath, 111 | "../../packages/codemirror/css/cypher-codemirror.css" 112 | ), 113 | "demo-base/css/app.css": path.resolve(basePath, "../demo-base/css/app.css") 114 | }; 115 | 116 | resolve = { 117 | ...resolve, 118 | modules: [...(resolve.modules || []), ...modulePackages], 119 | alias: { ...(resolve.alias || {}), ...extraAlias, ...packageToEntryFileMap }, 120 | extensions: [".js", ".json"] 121 | }; 122 | 123 | let rules = ( 124 | webpackConfig.module.rules ? webpackConfig.module.rules : [] 125 | ).slice(); 126 | 127 | for (let packageName of Object.keys(packageToSrcPathMap)) { 128 | const packageSrcPath = packageToSrcPathMap[packageName]; 129 | 130 | const options = { 131 | // babelrcRoots: packageSrcPath, 132 | cacheDirectory: babelCacheDirectory, 133 | configFile: babelConfigPath 134 | }; 135 | 136 | rules.push({ 137 | test: sourceRegexp, 138 | loader: "babel-loader", 139 | options: options, 140 | include: packageSrcPath 141 | }); 142 | } 143 | 144 | webpackConfig.resolve = resolve; 145 | webpackConfig.module.rules = rules; 146 | 147 | // console.log(JSON.stringify(webpackConfig, null, ' ')) 148 | 149 | module.exports = webpackConfig; 150 | -------------------------------------------------------------------------------- /demos/demo-codemirror-6-webpack-svelte/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "demo-codemirror-6-webpack-svelte", 3 | "private": true, 4 | "version": "1.0.5", 5 | "scripts": { 6 | "startNoLocal": "cross-env NODE_ENV=\"development\" webpack serve", 7 | "start": "cross-env NODE_ENV=\"development\" webpack serve --config ./webpack.local.config.js", 8 | "e2e": "export PORT=5177; playwright test --config=../../playwright.config.js", 9 | "e2e:selector": "playwright codegen http://localhost:5177", 10 | "deploy": "npm run clean:deploy && cross-env NODE_ENV=\"production\" webpack", 11 | "clean:deploy": "rimraf dist", 12 | "check": "svelte-check --tsconfig ./tsconfig.json", 13 | "serve": "pm2 serve dist 5177 --spa --name demo5177", 14 | "unserve": "pm2 delete demo5177" 15 | }, 16 | "dependencies": { 17 | "@codemirror/autocomplete": "^6.3.4", 18 | "@codemirror/commands": "^6.1.2", 19 | "@codemirror/language": "^6.3.1", 20 | "@codemirror/lint": "^6.1.0", 21 | "@codemirror/search": "^6.2.3", 22 | "@codemirror/state": "^6.1.4", 23 | "@codemirror/view": "^6.6.0", 24 | "@lezer/highlight": "^1.1.3", 25 | "@neo4j-cypher/codemirror": "1.0.3", 26 | "@neo4j-cypher/svelte-codemirror": "1.0.5", 27 | "demo-base": "1.0.0", 28 | "demo-base-svelte": "1.0.0", 29 | "neo4j-driver": "^5.3.0" 30 | }, 31 | "devDependencies": { 32 | "@tsconfig/svelte": "^3.0.0", 33 | "babel-loader": "^9.1.0", 34 | "cross-env": "^7.0.3", 35 | "css-loader": "^6.7.2", 36 | "css-minimizer-webpack-plugin": "^4.2.2", 37 | "file-loader": "^6.2.0", 38 | "html-webpack-deploy-plugin": "^3.0.0", 39 | "html-webpack-plugin": "^5.5.0", 40 | "mini-css-extract-plugin": "^2.7.1", 41 | "style-loader": "^3.3.1", 42 | "svelte": "^3.53.1", 43 | "svelte-check": "^2.10.0", 44 | "svelte-loader": "^3.1.4", 45 | "svelte-preprocess": "^4.10.7", 46 | "terser-webpack-plugin": "^5.3.6", 47 | "tsconfig-paths-webpack-plugin": "^4.0.0", 48 | "tslib": "^2.4.1", 49 | "typescript": "^4.9.3", 50 | "url-loader": "^4.1.1", 51 | "webpack": "^5.75.0", 52 | "webpack-cli": "^5.0.0", 53 | "webpack-dev-server": "^4.11.1" 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /demos/demo-codemirror-6-webpack-svelte/public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /demos/demo-codemirror-6-webpack-svelte/src/App.svelte: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 14 | 15 | -------------------------------------------------------------------------------- /demos/demo-codemirror-6-webpack-svelte/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | cm-6-webpack-svelte 8 | 9 | 10 |
11 | 12 | 13 | -------------------------------------------------------------------------------- /demos/demo-codemirror-6-webpack-svelte/src/main.js: -------------------------------------------------------------------------------- 1 | import "demo-base/css/app.css"; 2 | import App from "./App.svelte"; 3 | 4 | const app = new App({ 5 | target: document.getElementById("app") 6 | }); 7 | 8 | export default app; 9 | -------------------------------------------------------------------------------- /demos/demo-codemirror-6-webpack-svelte/svelte.config.js: -------------------------------------------------------------------------------- 1 | import sveltePreprocess from "svelte-preprocess"; 2 | 3 | export default { 4 | compilerOptions: { 5 | enableSourcemap: true 6 | }, 7 | preprocess: sveltePreprocess({ 8 | sourceMap: true 9 | }) 10 | }; 11 | 12 | // export default { 13 | // // Consult https://github.com/sveltejs/svelte-preprocess 14 | // // for more information about preprocessors 15 | // preprocess: sveltePreprocess() 16 | // }; 17 | -------------------------------------------------------------------------------- /demos/demo-codemirror-6-webpack-svelte/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@tsconfig/svelte/tsconfig.json", 3 | "compilerOptions": { 4 | "target": "ESNext", 5 | "useDefineForClassFields": true, 6 | "module": "ESNext", 7 | "resolveJsonModule": true, 8 | "baseUrl": ".", 9 | /** 10 | * Typecheck JS in `.svelte` and `.js` files by default. 11 | * Disable checkJs if you'd like to use dynamic types in JS. 12 | * Note that setting allowJs false does not prevent the use 13 | * of JS in `.svelte` files. 14 | */ 15 | "allowJs": true, 16 | "checkJs": true, 17 | "isolatedModules": true 18 | }, 19 | "include": ["src/**/*.d.ts", "src/**/*.ts", "src/**/*.js", "src/**/*.svelte"], 20 | "references": [{ "path": "./tsconfig.node.json" }] 21 | } 22 | -------------------------------------------------------------------------------- /demos/demo-codemirror-6-webpack-svelte/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "module": "ESNext", 5 | "moduleResolution": "Node" 6 | }, 7 | "include": ["vite.config.ts"] 8 | } 9 | -------------------------------------------------------------------------------- /demos/demo-codemirror-6-webpack-svelte/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | const Webpack = require("webpack"); 3 | const HtmlWebpackPlugin = require("html-webpack-plugin"); 4 | const HtmlWebpackDeployPlugin = require("html-webpack-deploy-plugin"); 5 | const MiniCssExtractPlugin = require("mini-css-extract-plugin"); 6 | // const TsconfigPathsPlugin = require("tsconfig-paths-webpack-plugin"); 7 | const sveltePreprocess = require("svelte-preprocess"); 8 | 9 | const { NODE_ENV } = process.env; 10 | 11 | const mode = NODE_ENV; 12 | const isDev = mode !== "production"; 13 | 14 | const basePath = __dirname; 15 | const USE_STATIC = false; 16 | const publicPath = USE_STATIC ? "/static/" : "/"; 17 | 18 | const babelConfigPath = path.join(__dirname, "../../babel.config.js"); 19 | const babelES6ConfigPath = path.join(__dirname, "../../babel.es6.config.js"); 20 | 21 | module.exports = { 22 | resolve: { 23 | alias: { 24 | svelte: path.resolve(basePath, "../../node_modules", "svelte") 25 | // '@neo4j-cypher/codemirror': path.resolve(basePath, '../codemirror') 26 | }, 27 | modules: [ 28 | path.resolve(basePath, "../../node_modules"), 29 | path.resolve(basePath, "node_modules") 30 | // path.resolve(basePath, 'packages'), 31 | // path.resolve(basePath, 'src') 32 | ], 33 | extensions: [".js", ".jsx", ".ts", ".tsx", ".mjs", ".svelte"], 34 | // plugins: [new TsconfigPathsPlugin({ configFile: './tsconfig.json' })], 35 | mainFields: ["svelte", "browser", "module", "main"] 36 | }, 37 | mode: NODE_ENV, 38 | entry: [path.join(basePath, "src/main.js")], 39 | output: { 40 | filename: "app-[hash].js", 41 | chunkFilename: "[name]-[hash].bundle.js", 42 | // publicPath: publicPath, 43 | publicPath, 44 | path: USE_STATIC 45 | ? path.join(basePath, "dist/static") 46 | : path.join(basePath, "dist") 47 | }, 48 | plugins: [ 49 | new Webpack.DefinePlugin({ 50 | PUBLIC_PATH: JSON.stringify(publicPath) 51 | }), 52 | new MiniCssExtractPlugin({ 53 | filename: "[name].css", 54 | chunkFilename: "[id].css" 55 | }), 56 | new HtmlWebpackPlugin({ 57 | template: "src/index.html", 58 | path: "dist", 59 | filename: USE_STATIC ? "../index.html" : "index.html" 60 | // favicon: 'src/favicon.ico' 61 | }), 62 | new HtmlWebpackDeployPlugin({ 63 | addAssetsPath: (assetPath) => assetPath, 64 | assets: { 65 | copy: [{ from: "../../packages/codemirror/css", to: "css/" }], 66 | links: ["css/cypher-codemirror.css"] 67 | } 68 | }) 69 | ], 70 | module: { 71 | rules: [ 72 | // { 73 | // // test: /\.(html|svelte)$/, 74 | // test: /\.svelte$/, 75 | // use: 'svelte-loader' 76 | // } 77 | { 78 | test: /\.svelte$/, 79 | // test: /\.(html|svelte)$/, 80 | use: [ 81 | { 82 | loader: "babel-loader", 83 | options: { 84 | configFile: babelES6ConfigPath 85 | } 86 | }, 87 | { 88 | loader: "svelte-loader", 89 | options: { 90 | emitCss: true, 91 | preprocess: sveltePreprocess({ sourceMap: true }), 92 | dev: isDev, 93 | compilerOptions: { 94 | enableSourcemap: true 95 | } 96 | } 97 | } 98 | ] 99 | }, 100 | // { 101 | // // required to prevent errors from Svelte on Webpack 5+, omit on Webpack 4 102 | // test: /node_modules\/svelte\/.*\.mjs$/, 103 | // resolve: { 104 | // fullySpecified: false 105 | // } 106 | // }, 107 | { 108 | test: /\.(js|jsx|ts|tsx)$/, 109 | // "include" will fail the transpile 110 | // include: [path.join(basePath, 'src')], 111 | exclude: /node_modules/, 112 | loader: "babel-loader", 113 | options: { 114 | configFile: babelConfigPath 115 | } 116 | }, 117 | // Disable sass for now 118 | // { 119 | // test: /\.scss$/, 120 | // // include: sassPath, 121 | // exclude: /node_modules/, 122 | // use: [ 123 | // MiniCssExtractPlugin.loader, 124 | // "css-loader", 125 | // "sass-loader" 126 | // ] 127 | // }, 128 | { 129 | test: /\.css$/, // global css files that don't need any processing 130 | // include: [path.join(basePath, 'src')], 131 | use: ["style-loader", "css-loader"] 132 | }, 133 | { 134 | test: /\.(png|gif|jpg|svg)$/, 135 | include: [path.join(basePath, "src")], 136 | use: "file-loader?limit=20480&name=assets/[name]-[hash].[ext]" 137 | }, 138 | { 139 | test: /\.woff$/, 140 | include: [path.join(basePath, "src")], 141 | use: "file-loader?limit=65000&mimetype=application/font-woff&name=assets/fonts/[name].[ext]" 142 | }, 143 | { 144 | test: /\.woff2$/, 145 | include: [path.join(basePath, "src")], 146 | use: "file-loader?limit=65000&mimetype=application/font-woff2&name=assets/fonts/[name].[ext]" 147 | }, 148 | { 149 | test: /\.[ot]tf$/, 150 | include: [path.join(basePath, "src")], 151 | use: "file-loader?limit=65000&mimetype=application/octet-stream&name=assets/fonts/[name].[ext]" 152 | }, 153 | { 154 | test: /\.eot$/, 155 | include: [path.join(basePath, "src")], 156 | use: "file-loader?limit=65000&mimetype=application/vnd.ms-fontobject&name=assets/fonts/[name].[ext]" 157 | } 158 | ] 159 | }, 160 | optimization: {}, 161 | // devtool: isDev ? 'cheap-module-source-map' : 'source-map', 162 | devtool: isDev ? "eval-source-map" : "source-map", 163 | devServer: { 164 | host: "0.0.0.0", 165 | port: 5177, 166 | historyApiFallback: USE_STATIC ? { index: "/static/../index.html" } : true 167 | } 168 | }; 169 | -------------------------------------------------------------------------------- /demos/demo-codemirror-6-webpack-svelte/webpack.local.config.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | const fs = require("fs"); 3 | 4 | const webpackConfig = require("./webpack.config"); 5 | 6 | const namedPackages = [ 7 | "@neo4j-cypher/codemirror", 8 | "@neo4j-cypher/editor-support", 9 | // "@neo4j-cypher/react-codemirror", 10 | "@neo4j-cypher/svelte-codemirror" 11 | ].map((name) => ({ name, type: "named" })); 12 | 13 | const indexPackages = [ 14 | "@neo4j-cypher/antlr4", 15 | "@neo4j-cypher/antlr4-simple", 16 | "@neo4j-cypher/extract-statements" 17 | ].map((name) => ({ name, type: "index" })); 18 | 19 | const demoPackages = [ 20 | "demo-base", 21 | // "demo-base-react", 22 | "demo-base-svelte" 23 | ].map((name) => ({ name, type: "demo" })); 24 | 25 | const allPackages = namedPackages.concat(indexPackages).concat(demoPackages); 26 | 27 | const localPackages = allPackages.reduce((lp, pkg) => { 28 | const { name, type } = pkg; 29 | const pathName = name.includes("/") 30 | ? name.substring(name.indexOf("/") + 1) 31 | : name; 32 | const basePath = type === "demo" ? "../" : "../../packages/"; 33 | lp[name] = { 34 | rootPath: basePath + pathName, 35 | entry: { 36 | srcPath: "src", 37 | entryFile: type === "named" ? pathName + ".js" : "index.js" 38 | } 39 | }; 40 | return lp; 41 | }, {}); 42 | 43 | const basePath = process.cwd(); 44 | const babelConfigPath = path.join(__dirname, "../../babel.config.js"); 45 | 46 | const modulePackages = [path.join(basePath, "../../node_modules")]; 47 | 48 | const description = "Local Packages Map"; 49 | const babelCacheDirectory = true; 50 | const sourceRegexp = /\.js?$/; 51 | 52 | const packageToEntryFileMap = {}; 53 | const packageToSrcPathMap = {}; 54 | 55 | let stats; 56 | let foundSrcPath; 57 | let foundEntryFile; 58 | let allFound = true; 59 | 60 | for (let packageName of Object.keys(localPackages)) { 61 | const packageObject = localPackages[packageName]; 62 | 63 | const { rootPath, entry } = packageObject; 64 | if (entry !== undefined) { 65 | const { srcPath, entryFile } = entry; 66 | const localSrcPath = path.join(rootPath || "", srcPath || ""); 67 | const localEntryFile = path.join(localSrcPath, entryFile); 68 | try { 69 | foundSrcPath = path.resolve(basePath, localSrcPath); 70 | foundEntryFile = path.resolve(basePath, localEntryFile); 71 | stats = fs.statSync(foundEntryFile); 72 | if (stats.isDirectory() || stats.isFile()) { 73 | packageToEntryFileMap[packageName] = foundEntryFile; 74 | packageToSrcPathMap[packageName] = foundSrcPath; 75 | console.log( 76 | description + " - resource found: ", 77 | packageName, 78 | foundEntryFile 79 | ); 80 | } else { 81 | console.warn( 82 | description + " - resource was not a file or directory: ", 83 | packageName, 84 | localEntryFile 85 | ); 86 | allFound = false; 87 | } 88 | } catch (error) { 89 | console.warn( 90 | description + " - error loading resource: ", 91 | packageName, 92 | localEntryFile 93 | ); 94 | allFound = false; 95 | } 96 | } 97 | } 98 | if (!allFound) { 99 | console.warn( 100 | description + " - base path for the above errors was: ", 101 | basePath 102 | ); 103 | process.exit(1); 104 | } 105 | 106 | let resolve = webpackConfig.resolve || {}; 107 | 108 | const extraAlias = { 109 | "@neo4j-cypher/codemirror/css/cypher-codemirror.css": path.resolve( 110 | basePath, 111 | "../../packages/codemirror/css/cypher-codemirror.css" 112 | ), 113 | "demo-base/css/app.css": path.resolve(basePath, "../demo-base/css/app.css") 114 | }; 115 | 116 | resolve = { 117 | ...resolve, 118 | modules: [...(resolve.modules || []), ...modulePackages], 119 | alias: { ...(resolve.alias || {}), ...extraAlias, ...packageToEntryFileMap }, 120 | extensions: [".js", ".json"] 121 | }; 122 | 123 | let rules = ( 124 | webpackConfig.module.rules ? webpackConfig.module.rules : [] 125 | ).slice(); 126 | 127 | for (let packageName of Object.keys(packageToSrcPathMap)) { 128 | const packageSrcPath = packageToSrcPathMap[packageName]; 129 | 130 | const options = { 131 | // babelrcRoots: packageSrcPath, 132 | cacheDirectory: babelCacheDirectory, 133 | configFile: babelConfigPath 134 | }; 135 | 136 | rules.push({ 137 | test: sourceRegexp, 138 | loader: "babel-loader", 139 | options: options, 140 | include: packageSrcPath 141 | }); 142 | } 143 | 144 | webpackConfig.resolve = resolve; 145 | webpackConfig.module.rules = rules; 146 | 147 | // console.log(JSON.stringify(webpackConfig, null, ' ')) 148 | 149 | module.exports = webpackConfig; 150 | -------------------------------------------------------------------------------- /demos/demo-vitest/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # demo-vitest 2 | 3 | ## 1.0.4 4 | 5 | ### Patch Changes 6 | 7 | - @neo4j-cypher/react-codemirror@1.0.4 8 | 9 | ## 1.0.3 10 | 11 | ### Patch Changes 12 | 13 | - Updated dependencies [eaf7435] 14 | - Updated dependencies [44d7f5f] 15 | - @neo4j-cypher/react-codemirror@1.0.3 16 | 17 | ## 1.0.2 18 | 19 | ### Patch Changes 20 | 21 | - Updated dependencies [f14489b] 22 | - @neo4j-cypher/react-codemirror@1.0.2 23 | 24 | ## 1.0.1 25 | 26 | ### Patch Changes 27 | 28 | - Updated dependencies [c1989f8] 29 | - @neo4j-cypher/react-codemirror@1.0.1 30 | 31 | ## 1.0.0 32 | 33 | ### Patch Changes 34 | 35 | - 8ba2deb: Exit pre-release mode 36 | - 8549a61: Apply workaround for node 18.14.0 support 37 | - acd35e1: Update repo url after move 38 | - 45a590b: Change license from GPL-3.0 to Apache-2.0 39 | - 91cb80a: Fix module exports + add shallow comparision on schema updates 40 | - Updated dependencies [4af77ae] 41 | - Updated dependencies [896eddf] 42 | - Updated dependencies [8ba2deb] 43 | - Updated dependencies [b35f29a] 44 | - Updated dependencies [b5ca4c5] 45 | - Updated dependencies [4a8e102] 46 | - Updated dependencies [de33476] 47 | - Updated dependencies [0a21042] 48 | - Updated dependencies [95e70e0] 49 | - Updated dependencies [8549a61] 50 | - Updated dependencies [42dc131] 51 | - Updated dependencies [95e6d25] 52 | - Updated dependencies [48363de] 53 | - Updated dependencies [77cb7d3] 54 | - Updated dependencies [acd35e1] 55 | - Updated dependencies [1d97f58] 56 | - Updated dependencies [45a590b] 57 | - Updated dependencies [91cb80a] 58 | - Updated dependencies [13f7151] 59 | - @neo4j-cypher/react-codemirror@1.0.0 60 | 61 | ## 1.0.0-next.5 62 | 63 | ### Patch Changes 64 | 65 | - 8549a61: Apply workaround for node 18.14.0 support 66 | - Updated dependencies [8549a61] 67 | - @neo4j-cypher/react-codemirror@1.0.0-next.25 68 | 69 | ## 1.0.0-next.4 70 | 71 | ### Patch Changes 72 | 73 | - acd35e1: Update repo url after move 74 | - 45a590b: Change license from GPL-3.0 to Apache-2.0 75 | - Updated dependencies [acd35e1] 76 | - Updated dependencies [45a590b] 77 | - @neo4j-cypher/react-codemirror@1.0.0-next.24 78 | 79 | ## 1.0.0-next.3 80 | 81 | ### Patch Changes 82 | 83 | - Updated dependencies [1d97f58] 84 | - @neo4j-cypher/react-codemirror@1.0.0-next.23 85 | 86 | ## 1.0.0-next.2 87 | 88 | ### Patch Changes 89 | 90 | - 91cb80a: Fix module exports + add shallow comparision on schema updates 91 | - Updated dependencies [91cb80a] 92 | - @neo4j-cypher/react-codemirror@1.0.0-next.22 93 | -------------------------------------------------------------------------------- /demos/demo-vitest/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vitest React Demo 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /demos/demo-vitest/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "demo-vitest", 3 | "private": true, 4 | "description": "demo of tests of the editor using vitest", 5 | "keywords": [], 6 | "version": "1.0.4", 7 | "author": "Neo4j Inc.", 8 | "license": "Apache-2.0", 9 | "type": "module", 10 | "repository": { 11 | "type": "git", 12 | "url": "git://github.com/neo4j/cypher-editor.git" 13 | }, 14 | "bugs": { 15 | "url": "https://github.com/neo4j/cypher-editor/issues" 16 | }, 17 | "scripts": { 18 | "dev": "vite", 19 | "build": "tsc && vite build", 20 | "preview": "vite preview", 21 | "test": "vitest" 22 | }, 23 | "engineStrict": true, 24 | "engines": { 25 | "node": ">=16" 26 | }, 27 | "dependencies": { 28 | "@neo4j-cypher/react-codemirror": "1.0.4" 29 | }, 30 | "devDependencies": { 31 | "@testing-library/jest-dom": "^5.16.5", 32 | "@testing-library/react": "^13.4.0", 33 | "@vitejs/plugin-react": "^3.1.0", 34 | "jsdom": "^21.1.0", 35 | "react": "^18.2.0", 36 | "react-dom": "^18.2.0", 37 | "typescript": "^4.9.5", 38 | "vite": "^4.1.1", 39 | "vitest": "^0.28.5" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /demos/demo-vitest/public/vite.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /demos/demo-vitest/src/App.test.tsx: -------------------------------------------------------------------------------- 1 | import { render, screen } from "@testing-library/react"; 2 | import App from "./App"; 3 | 4 | describe("App", () => { 5 | it("should render", () => { 6 | render(); 7 | expect(screen.getByText("test_value")).toBeInTheDocument(); 8 | }); 9 | }); 10 | -------------------------------------------------------------------------------- /demos/demo-vitest/src/App.tsx: -------------------------------------------------------------------------------- 1 | import { CypherEditor } from "@neo4j-cypher/react-codemirror"; 2 | 3 | function App() { 4 | return ; 5 | } 6 | 7 | export default App; 8 | -------------------------------------------------------------------------------- /demos/demo-vitest/src/main.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import ReactDOM from "react-dom/client"; 3 | import App from "./App"; 4 | 5 | ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render( 6 | 7 | 8 | 9 | ); 10 | -------------------------------------------------------------------------------- /demos/demo-vitest/src/testUtils/setup.ts: -------------------------------------------------------------------------------- 1 | import "@testing-library/jest-dom"; 2 | -------------------------------------------------------------------------------- /demos/demo-vitest/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ESNext", 4 | "types": ["vitest/globals"], 5 | "useDefineForClassFields": true, 6 | "lib": ["DOM", "DOM.Iterable", "ESNext"], 7 | "allowJs": false, 8 | "skipLibCheck": true, 9 | "esModuleInterop": false, 10 | "allowSyntheticDefaultImports": true, 11 | "strict": true, 12 | "forceConsistentCasingInFileNames": true, 13 | "module": "ESNext", 14 | "moduleResolution": "Node", 15 | "resolveJsonModule": true, 16 | "isolatedModules": true, 17 | "noEmit": true, 18 | "jsx": "react-jsx" 19 | }, 20 | "include": ["**/*.ts", "**/*.tsx"], 21 | "exclude": ["node_modules"], 22 | "references": [{ "path": "./tsconfig.node.json" }] 23 | } 24 | -------------------------------------------------------------------------------- /demos/demo-vitest/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "module": "ESNext", 5 | "moduleResolution": "Node", 6 | "allowSyntheticDefaultImports": true 7 | }, 8 | "include": ["vite.config.ts"] 9 | } 10 | -------------------------------------------------------------------------------- /demos/demo-vitest/vite.config.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | 4 | import react from "@vitejs/plugin-react"; 5 | import { defineConfig } from "vite"; 6 | 7 | // https://vitejs.dev/config/ 8 | export default defineConfig({ 9 | plugins: [react()], 10 | test: { 11 | globals: true, 12 | environment: "jsdom", 13 | setupFiles: "./src/testUtils/setup.ts", 14 | css: true 15 | } 16 | }); 17 | -------------------------------------------------------------------------------- /docs/generated/index.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | [Home](./index.md) 4 | 5 | ## API Reference 6 | 7 | ### Packages: 8 | 9 | | Package | Description | 10 | | --- | --- | 11 | | [@neo4j-cypher/codemirror](./neo4j-cypher_codemirror.md) | Adds support for the cypher query language to Codemirror version 6 | 12 | | [@neo4j-cypher/editor-support](./neo4j-cypher_editor-support.md) | Cypher language support package using an antlr4 grammar | 13 | | [@neo4j-cypher/react-codemirror](./neo4j-cypher_react-codemirror.md) | This package provides a React Cypher Editor component | 14 | | [@neo4j-cypher/svelte-codemirror](./neo4j-cypher_svelte-codemirror.md) | This package provides a Svelte Cypher Editor component | 15 | 16 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "devDependencies": { 4 | "@babel/cli": "^7.20.7", 5 | "@babel/core": "^7.20.12", 6 | "@babel/plugin-proposal-class-properties": "^7.18.6", 7 | "@babel/plugin-proposal-object-rest-spread": "^7.20.7", 8 | "@babel/plugin-transform-react-display-name": "^7.18.6", 9 | "@babel/plugin-transform-react-jsx": "^7.20.13", 10 | "@babel/plugin-transform-runtime": "^7.19.6", 11 | "@babel/preset-env": "^7.20.2", 12 | "@playwright/test": "^1.30.0", 13 | "api-docdown": "^1.0.2", 14 | "cross-env": "^7.0.3", 15 | "pm2": "^5.2.2", 16 | "prettier": "^2.8.4", 17 | "prettier-plugin-svelte": "^2.9.0", 18 | "pretty-quick": "^3.1.3", 19 | "rimraf": "^3.0.2", 20 | "turbo": "^1.7.4" 21 | }, 22 | "workspaces": [ 23 | "packages/*", 24 | "demos/*", 25 | "apps/*" 26 | ], 27 | "scripts": { 28 | "build:demos": "turbo run deploy --filter='!./apps/*'", 29 | "build:libs": "turbo run build", 30 | "build:docs": "api-docdown generate", 31 | "build:docs-extract": "api-docdown extract", 32 | "build:docs-document": "api-docdown document", 33 | "clean:all": "turbo run clean:deploy clean:build && npm run clean:packages", 34 | "clean:demos": "turbo run clean:deploy", 35 | "clean:packages": "rimraf packages/*/node_modules; rimraf demos/*/node_modules; rimraf apps/*/node_modules; rimraf node_modules;", 36 | "clean:libs": "turbo run clean:build", 37 | "turbo": "turbo", 38 | "pm2": "pm2", 39 | "prepublishOnly": "npm run build:libs", 40 | "prettier": "prettier --write .", 41 | "start:demos": "turbo run start", 42 | "start:e2e": "turbo run e2e --filter='!./apps/*'", 43 | "stop:e2e": "turbo run unserve", 44 | "release": "changeset version && npm i --package-lock-only --install-links=false && git add . && git commit -am \"Release\"", 45 | "publish": "npm run build:libs && npm run build:demos && changeset publish" 46 | }, 47 | "name": "cypher-editor", 48 | "dependencies": { 49 | "@changesets/cli": "^2.26.0" 50 | }, 51 | "engines": { 52 | "npm": "8.x || 9.x", 53 | "node": "18.x" 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /packages/antlr4-browser/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @neo4j-cypher/antlr4-browser 2 | 3 | ## 1.0.0 4 | 5 | ### Major Changes 6 | 7 | - 48363de: add antlr4-browser package (remove fs dependency) 8 | 9 | ### Patch Changes 10 | 11 | - 8ba2deb: Exit pre-release mode 12 | - 8549a61: Apply workaround for node 18.14.0 support 13 | - acd35e1: Update repo url after move 14 | - 45a590b: Change license from GPL-3.0 to Apache-2.0 15 | - 91cb80a: Fix module exports + add shallow comparision on schema updates 16 | 17 | ## 1.0.0-next.3 18 | 19 | ### Patch Changes 20 | 21 | - 8549a61: Apply workaround for node 18.14.0 support 22 | 23 | ## 1.0.0-next.2 24 | 25 | ### Patch Changes 26 | 27 | - acd35e1: Update repo url after move 28 | - 45a590b: Change license from GPL-3.0 to Apache-2.0 29 | 30 | ## 1.0.0-next.1 31 | 32 | ### Patch Changes 33 | 34 | - 91cb80a: Fix module exports + add shallow comparision on schema updates 35 | 36 | ## 1.0.0-next.0 37 | 38 | ### Major Changes 39 | 40 | - 48363de: add antlr4-browser package (remove fs dependency) 41 | -------------------------------------------------------------------------------- /packages/antlr4-browser/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@neo4j-cypher/antlr4-browser", 3 | "description": "Wraps antlr4 in a browser consumable format without node dependencies", 4 | "keywords": [ 5 | "antlr4", 6 | "browser" 7 | ], 8 | "version": "1.0.0", 9 | "author": "Neo4j Inc.", 10 | "license": "Apache-2.0", 11 | "main": "./lib/index.js", 12 | "module": "./es/index.js", 13 | "exports": { 14 | ".": { 15 | "import": "./es/index.js", 16 | "require": "./lib/index.js" 17 | }, 18 | "./src/index.js": { 19 | "import": "./src/index.js" 20 | } 21 | }, 22 | "repository": { 23 | "type": "git", 24 | "url": "git://github.com/neo4j/cypher-editor.git" 25 | }, 26 | "bugs": { 27 | "url": "https://github.com/neo4j/cypher-editor/issues" 28 | }, 29 | "scripts": { 30 | "build-lib": "babel --config-file ../../babel.antlr4-browser.config.js --extensions \".js\" --out-dir lib ./src", 31 | "build-es": "cross-env ES=true babel --config-file ../../babel.antlr4-browser.config.js --extensions \".js\" --out-dir es ./src", 32 | "build": "npm run build-lib && npm run build-es", 33 | "clean:build": "rimraf lib && rimraf es" 34 | }, 35 | "files": [ 36 | "es/", 37 | "lib/", 38 | "README.md" 39 | ], 40 | "engineStrict": true, 41 | "engines": { 42 | "node": ">=16" 43 | }, 44 | "dependencies": { 45 | "@babel/runtime": "^7.20.13", 46 | "antlr4": "4.10.1" 47 | }, 48 | "devDependencies": { 49 | "@babel/cli": "^7.20.7", 50 | "@babel/core": "^7.20.12", 51 | "@babel/plugin-proposal-class-properties": "^7.18.6", 52 | "@babel/plugin-proposal-object-rest-spread": "^7.20.7", 53 | "@babel/plugin-transform-regenerator": "^7.20.5", 54 | "@babel/plugin-transform-runtime": "^7.19.6", 55 | "@babel/preset-env": "^7.20.2", 56 | "babel-plugin-filter-imports": "^4.0.0" 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /packages/antlr4-browser/src/index.js: -------------------------------------------------------------------------------- 1 | import "antlr4/src/antlr4/utils/stringHashCode.js"; 2 | import "antlr4/src/antlr4/polyfills/codepointat.js"; 3 | import "antlr4/src/antlr4/polyfills/fromcodepoint.js"; 4 | import { default as atn } from "antlr4/src/antlr4/atn/index.js"; 5 | import { default as dfa } from "antlr4/src/antlr4/dfa/index.js"; 6 | import { default as tree } from "antlr4/src/antlr4/tree/index.js"; 7 | import { default as error } from "antlr4/src/antlr4/error/index.js"; 8 | import Token from "antlr4/src/antlr4/Token.js"; 9 | import CommonToken from "antlr4/src/antlr4/CommonToken.js"; 10 | // import { default as CharStreams } from 'antlr4/src/antlr4/CharStreams.js'; 11 | import InputStream from "antlr4/src/antlr4/InputStream.js"; 12 | // import FileStream from 'antlr4/src/antlr4/FileStream.js'; 13 | import CommonTokenStream from "antlr4/src/antlr4/CommonTokenStream.js"; 14 | import Lexer from "antlr4/src/antlr4/Lexer.js"; 15 | import Parser from "antlr4/src/antlr4/Parser.js"; 16 | import PredictionContextCache from "antlr4/src/antlr4/atn/PredictionContextCache.js"; 17 | import ParserRuleContext from "antlr4/src/antlr4/context/ParserRuleContext.js"; 18 | import Interval from "antlr4/src/antlr4/misc/Interval.js"; 19 | import IntervalSet from "antlr4/src/antlr4/misc/IntervalSet.js"; 20 | import LL1Analyzer from "antlr4/src/antlr4/atn/LL1Analyzer.js"; 21 | import { default as Utils } from "antlr4/src/antlr4/utils/index.js"; 22 | 23 | const antlr4 = { 24 | atn, 25 | dfa, 26 | tree, 27 | error, 28 | Token, 29 | CommonToken, 30 | /* CharStreams, */ 31 | InputStream, 32 | /* FileStream, */ 33 | CommonTokenStream, 34 | Lexer, 35 | Parser, 36 | PredictionContextCache, 37 | ParserRuleContext, 38 | Interval, 39 | IntervalSet, 40 | LL1Analyzer, 41 | Utils 42 | }; 43 | 44 | export default antlr4; 45 | -------------------------------------------------------------------------------- /packages/antlr4-simple/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @neo4j-cypher/antlr4-simple 2 | 3 | ## 1.0.0 4 | 5 | ### Major Changes 6 | 7 | - 13f7151: Initial pre-release 8 | 9 | ### Patch Changes 10 | 11 | - 896eddf: add missing @babel/runtime dependency 12 | - 8ba2deb: Exit pre-release mode 13 | - 8549a61: Apply workaround for node 18.14.0 support 14 | - 48363de: add antlr4-browser package (remove fs dependency) 15 | - acd35e1: Update repo url after move 16 | - 45a590b: Change license from GPL-3.0 to Apache-2.0 17 | - 91cb80a: Fix module exports + add shallow comparision on schema updates 18 | - Updated dependencies [8ba2deb] 19 | - Updated dependencies [8549a61] 20 | - Updated dependencies [48363de] 21 | - Updated dependencies [acd35e1] 22 | - Updated dependencies [45a590b] 23 | - Updated dependencies [91cb80a] 24 | - @neo4j-cypher/antlr4-browser@1.0.0 25 | 26 | ## 1.0.0-next.5 27 | 28 | ### Patch Changes 29 | 30 | - 8549a61: Apply workaround for node 18.14.0 support 31 | - Updated dependencies [8549a61] 32 | - @neo4j-cypher/antlr4-browser@1.0.0-next.3 33 | 34 | ## 1.0.0-next.4 35 | 36 | ### Patch Changes 37 | 38 | - acd35e1: Update repo url after move 39 | - 45a590b: Change license from GPL-3.0 to Apache-2.0 40 | - Updated dependencies [acd35e1] 41 | - Updated dependencies [45a590b] 42 | - @neo4j-cypher/antlr4-browser@1.0.0-next.2 43 | 44 | ## 1.0.0-next.3 45 | 46 | ### Patch Changes 47 | 48 | - 91cb80a: Fix module exports + add shallow comparision on schema updates 49 | - Updated dependencies [91cb80a] 50 | - @neo4j-cypher/antlr4-browser@1.0.0-next.1 51 | 52 | ## 1.0.0-next.2 53 | 54 | ### Patch Changes 55 | 56 | - 48363de: add antlr4-browser package (remove fs dependency) 57 | - Updated dependencies [48363de] 58 | - @neo4j-cypher/antlr4-browser@1.0.0-next.0 59 | 60 | ## 1.0.0-next.1 61 | 62 | ### Patch Changes 63 | 64 | - 896eddf: add missing @babel/runtime dependency 65 | 66 | ## 1.0.0-next.0 67 | 68 | ### Major Changes 69 | 70 | - 13f7151: Initial pre-release 71 | -------------------------------------------------------------------------------- /packages/antlr4-simple/README.md: -------------------------------------------------------------------------------- 1 | ### @neo4j-cypher/antlr4-simple 2 | 3 | This package contains: 4 | 5 | - JavaScript code generated from a simplified antlr4 g4 grammar file. 6 | - The simplified antlr4 g4 grammar file. 7 | 8 | The antlr 4 java jar file used to generate the code is in the `@neo4j-cypher/antlr4` package. 9 | 10 | The `generate` script in `package.json` gives an example of how to generate the source code yourself. 11 | -------------------------------------------------------------------------------- /packages/antlr4-simple/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@neo4j-cypher/antlr4-simple", 3 | "description": "Cypher parser (simple) loaded from an antlr4 g4 file", 4 | "keywords": [ 5 | "cypher" 6 | ], 7 | "version": "1.0.0", 8 | "author": "Neo4j Inc.", 9 | "license": "Apache-2.0", 10 | "main": "./lib/index.js", 11 | "module": "./es/index.js", 12 | "exports": { 13 | ".": { 14 | "import": "./es/index.js", 15 | "require": "./lib/index.js" 16 | }, 17 | "./src/index.js": { 18 | "import": "./src/index.js" 19 | } 20 | }, 21 | "repository": { 22 | "type": "git", 23 | "url": "git://github.com/neo4j/cypher-editor.git" 24 | }, 25 | "bugs": { 26 | "url": "https://github.com/neo4j/cypher-editor/issues" 27 | }, 28 | "scripts": { 29 | "build-lib": "babel --config-file ../../babel.antlr4.config.js --extensions \".js\" --out-dir lib ./src", 30 | "build-es": "cross-env ES=true babel --config-file ../../babel.antlr4.config.js --extensions \".js\" --out-dir es ./src", 31 | "build": "npm run build-lib && npm run build-es", 32 | "clean:build": "rimraf lib && rimraf es", 33 | "generate": "java -jar ../antlr4/src/antlr-4.10.1-complete.jar -Dlanguage=JavaScript src/Cypher.g4" 34 | }, 35 | "files": [ 36 | "es/", 37 | "lib/", 38 | "README.md" 39 | ], 40 | "engineStrict": true, 41 | "engines": { 42 | "node": ">=16" 43 | }, 44 | "dependencies": { 45 | "@babel/runtime": "^7.20.13", 46 | "@neo4j-cypher/antlr4-browser": "1.0.0" 47 | }, 48 | "devDependencies": { 49 | "@babel/cli": "^7.20.7", 50 | "@babel/core": "^7.20.12", 51 | "@babel/plugin-proposal-class-properties": "^7.18.6", 52 | "@babel/plugin-proposal-object-rest-spread": "^7.20.7", 53 | "@babel/plugin-transform-regenerator": "^7.20.5", 54 | "@babel/plugin-transform-runtime": "^7.19.6", 55 | "@babel/preset-env": "^7.20.2", 56 | "babel-plugin-replace-imports": "^1.0.2" 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /packages/antlr4-simple/src/index.js: -------------------------------------------------------------------------------- 1 | import CypherLexer from "./CypherLexer"; 2 | import CypherListener from "./CypherListener"; 3 | import CypherParser from "./CypherParser"; 4 | 5 | export { CypherLexer, CypherListener, CypherParser }; 6 | -------------------------------------------------------------------------------- /packages/antlr4/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @neo4j-cypher/antlr4 2 | 3 | ## 1.0.0 4 | 5 | ### Major Changes 6 | 7 | - 13f7151: Initial pre-release 8 | 9 | ### Patch Changes 10 | 11 | - 896eddf: add missing @babel/runtime dependency 12 | - 8ba2deb: Exit pre-release mode 13 | - 8549a61: Apply workaround for node 18.14.0 support 14 | - 48363de: add antlr4-browser package (remove fs dependency) 15 | - acd35e1: Update repo url after move 16 | - 45a590b: Change license from GPL-3.0 to Apache-2.0 17 | - 91cb80a: Fix module exports + add shallow comparision on schema updates 18 | - Updated dependencies [8ba2deb] 19 | - Updated dependencies [8549a61] 20 | - Updated dependencies [48363de] 21 | - Updated dependencies [acd35e1] 22 | - Updated dependencies [45a590b] 23 | - Updated dependencies [91cb80a] 24 | - @neo4j-cypher/antlr4-browser@1.0.0 25 | 26 | ## 1.0.0-next.5 27 | 28 | ### Patch Changes 29 | 30 | - 8549a61: Apply workaround for node 18.14.0 support 31 | - Updated dependencies [8549a61] 32 | - @neo4j-cypher/antlr4-browser@1.0.0-next.3 33 | 34 | ## 1.0.0-next.4 35 | 36 | ### Patch Changes 37 | 38 | - acd35e1: Update repo url after move 39 | - 45a590b: Change license from GPL-3.0 to Apache-2.0 40 | - Updated dependencies [acd35e1] 41 | - Updated dependencies [45a590b] 42 | - @neo4j-cypher/antlr4-browser@1.0.0-next.2 43 | 44 | ## 1.0.0-next.3 45 | 46 | ### Patch Changes 47 | 48 | - 91cb80a: Fix module exports + add shallow comparision on schema updates 49 | - Updated dependencies [91cb80a] 50 | - @neo4j-cypher/antlr4-browser@1.0.0-next.1 51 | 52 | ## 1.0.0-next.2 53 | 54 | ### Patch Changes 55 | 56 | - 48363de: add antlr4-browser package (remove fs dependency) 57 | - Updated dependencies [48363de] 58 | - @neo4j-cypher/antlr4-browser@1.0.0-next.0 59 | 60 | ## 1.0.0-next.1 61 | 62 | ### Patch Changes 63 | 64 | - 896eddf: add missing @babel/runtime dependency 65 | 66 | ## 1.0.0-next.0 67 | 68 | ### Major Changes 69 | 70 | - 13f7151: Initial pre-release 71 | -------------------------------------------------------------------------------- /packages/antlr4/README.md: -------------------------------------------------------------------------------- 1 | ### @neo4j-cypher/antlr4 2 | 3 | This package contains: 4 | 5 | - JavaScript code generated from an antlr4 g4 grammar file. 6 | - The antlr4 g4 grammar file. 7 | - An antlr 4 java jar file used to generate the code. 8 | 9 | The `generate` script in `package.json` gives an example of how to generate the source code yourself. 10 | -------------------------------------------------------------------------------- /packages/antlr4/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@neo4j-cypher/antlr4", 3 | "description": "Cypher parser loaded from an antlr4 g4 file", 4 | "keywords": [ 5 | "cypher" 6 | ], 7 | "version": "1.0.0", 8 | "author": "Neo4j Inc.", 9 | "license": "Apache-2.0", 10 | "main": "./lib/index.js", 11 | "module": "./es/index.js", 12 | "exports": { 13 | ".": { 14 | "import": "./es/index.js", 15 | "require": "./lib/index.js" 16 | }, 17 | "./src/index.js": { 18 | "import": "./src/index.js" 19 | } 20 | }, 21 | "repository": { 22 | "type": "git", 23 | "url": "git://github.com/neo4j/cypher-editor.git" 24 | }, 25 | "bugs": { 26 | "url": "https://github.com/neo4j/cypher-editor/issues" 27 | }, 28 | "scripts": { 29 | "build-lib": "babel --config-file ../../babel.antlr4.config.js --extensions \".js\" --out-dir lib ./src", 30 | "build-es": "cross-env ES=true babel --config-file ../../babel.antlr4.config.js --extensions \".js\" --out-dir es ./src", 31 | "build": "npm run build-lib && npm run build-es", 32 | "clean:build": "rimraf lib && rimraf es", 33 | "generate": "java -jar src/antlr-4.10.1-complete.jar -Dlanguage=JavaScript src/Cypher.g4" 34 | }, 35 | "files": [ 36 | "es/", 37 | "lib/", 38 | "README.md" 39 | ], 40 | "engineStrict": true, 41 | "engines": { 42 | "node": ">=16" 43 | }, 44 | "dependencies": { 45 | "@babel/runtime": "^7.20.13", 46 | "@neo4j-cypher/antlr4-browser": "1.0.0" 47 | }, 48 | "devDependencies": { 49 | "@babel/cli": "^7.20.7", 50 | "@babel/core": "^7.20.12", 51 | "@babel/plugin-proposal-class-properties": "^7.18.6", 52 | "@babel/plugin-proposal-object-rest-spread": "^7.20.7", 53 | "@babel/plugin-transform-regenerator": "^7.20.5", 54 | "@babel/plugin-transform-runtime": "^7.19.6", 55 | "@babel/preset-env": "^7.20.2", 56 | "babel-plugin-replace-imports": "^1.0.2" 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /packages/antlr4/src/antlr-4.10.1-complete.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neo4j/cypher-editor/e212d963a9ac31742d170addec31ba285743c6ad/packages/antlr4/src/antlr-4.10.1-complete.jar -------------------------------------------------------------------------------- /packages/antlr4/src/index.js: -------------------------------------------------------------------------------- 1 | import CypherLexer from "./CypherLexer"; 2 | import CypherListener from "./CypherListener"; 3 | import CypherParser from "./CypherParser"; 4 | 5 | export { CypherLexer, CypherListener, CypherParser }; 6 | -------------------------------------------------------------------------------- /packages/codemirror/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @neo4j-cypher/codemirror 2 | 3 | ## 1.0.3 4 | 5 | ### Patch Changes 6 | 7 | - Updated dependencies [bdae809] 8 | - @neo4j-cypher/editor-support@1.0.2 9 | 10 | ## 1.0.2 11 | 12 | ### Patch Changes 13 | 14 | - f14489b: Add selection & onSelectionChanged options/props 15 | 16 | ## 1.0.1 17 | 18 | ### Patch Changes 19 | 20 | - c1989f8: add keyUp option/prop, improve autocomplete trigger logic 21 | - Updated dependencies [54698be] 22 | - @neo4j-cypher/editor-support@1.0.1 23 | 24 | ## 1.0.0 25 | 26 | ### Major Changes 27 | 28 | - 13f7151: Initial pre-release 29 | 30 | ### Patch Changes 31 | 32 | - 896eddf: add missing @babel/runtime dependency 33 | - 8ba2deb: Exit pre-release mode 34 | - a2750e5: add js theme override to remove focused outline 35 | - b35f29a: make sure calls to editorApi.set function apply defaults, fixup react types 36 | - b8d7618: fix issues with parsing emoji & special chars 37 | - b0dc3cb: fix css line-height of gutters to match content 38 | - b5ca4c5: rename indentWithTab -> tabKey, fix tab with autocomplete 39 | - 4a8e102: tooltipAbsolute default to true, fix tab key bugs 40 | - d925e37: fix default application bug on editor creation 41 | - de33476: Add indentWithTab prop / option 42 | - 0a21042: add bracketMatching & closeBrackets options (both default true) 43 | - de36649: Use escaped Cypher when needed in the auto-completions 44 | - b5add94: fix bug where decorations were not being cleared properly 45 | - 05bcaef: undo changes from last version, they broke things 46 | - 95e70e0: add tooltipAbsolute option / prop 47 | - 8549a61: Apply workaround for node 18.14.0 support 48 | - 42dc131: fix position/selection bug, add search & indentUnit options 49 | - 95e6d25: add cypherLanguage & various search/cursor options, misc improvements 50 | - 48363de: add antlr4-browser package (remove fs dependency) 51 | - 77cb7d3: add missing pre/post extensions props to components, fix autocomplete change typo bug 52 | - acd35e1: Update repo url after move 53 | - 45a590b: Change license from GPL-3.0 to Apache-2.0 54 | - 91cb80a: Fix module exports + add shallow comparision on schema updates 55 | - f20de4e: fix rare decoration update error by removing unneeded code 56 | - d4ef48e: disable syntax highlighting when editor is empty to fix a bug 57 | - d88078d: Fix paste bug that happened when the pasted contents was more than 32 lines 58 | - Updated dependencies [6e6269f] 59 | - Updated dependencies [896eddf] 60 | - Updated dependencies [8ba2deb] 61 | - Updated dependencies [8549a61] 62 | - Updated dependencies [48363de] 63 | - Updated dependencies [acd35e1] 64 | - Updated dependencies [45a590b] 65 | - Updated dependencies [91cb80a] 66 | - Updated dependencies [13f7151] 67 | - @neo4j-cypher/editor-support@1.0.0 68 | 69 | ## 1.0.0-next.23 70 | 71 | ### Patch Changes 72 | 73 | - 8549a61: Apply workaround for node 18.14.0 support 74 | - Updated dependencies [8549a61] 75 | - @neo4j-cypher/editor-support@1.0.0-next.6 76 | 77 | ## 1.0.0-next.22 78 | 79 | ### Patch Changes 80 | 81 | - acd35e1: Update repo url after move 82 | - 45a590b: Change license from GPL-3.0 to Apache-2.0 83 | - Updated dependencies [acd35e1] 84 | - Updated dependencies [45a590b] 85 | - @neo4j-cypher/editor-support@1.0.0-next.5 86 | 87 | ## 1.0.0-next.21 88 | 89 | ### Patch Changes 90 | 91 | - 91cb80a: Fix module exports + add shallow comparision on schema updates 92 | - Updated dependencies [91cb80a] 93 | - @neo4j-cypher/editor-support@1.0.0-next.4 94 | 95 | ## 1.0.0-next.20 96 | 97 | ### Patch Changes 98 | 99 | - d88078d: Fix paste bug that happened when the pasted contents was more than 32 lines 100 | 101 | ## 1.0.0-next.19 102 | 103 | ### Patch Changes 104 | 105 | - Updated dependencies [6e6269f] 106 | - @neo4j-cypher/editor-support@1.0.0-next.3 107 | 108 | ## 1.0.0-next.18 109 | 110 | ### Patch Changes 111 | 112 | - d4ef48e: disable syntax highlighting when editor is empty to fix a bug 113 | 114 | ## 1.0.0-next.17 115 | 116 | ### Patch Changes 117 | 118 | - b5add94: fix bug where decorations were not being cleared properly 119 | - 05bcaef: undo changes from last version, they broke things 120 | 121 | ## 1.0.0-next.16 122 | 123 | ### Patch Changes 124 | 125 | - f20de4e: fix rare decoration update error by removing unneeded code 126 | 127 | ## 1.0.0-next.15 128 | 129 | ### Patch Changes 130 | 131 | - b0dc3cb: fix css line-height of gutters to match content 132 | 133 | ## 1.0.0-next.14 134 | 135 | ### Patch Changes 136 | 137 | - 77cb7d3: add missing pre/post extensions props to components, fix autocomplete change typo bug 138 | 139 | ## 1.0.0-next.13 140 | 141 | ### Patch Changes 142 | 143 | - b8d7618: fix issues with parsing emoji & special chars 144 | - 0a21042: add bracketMatching & closeBrackets options (both default true) 145 | 146 | ## 1.0.0-next.12 147 | 148 | ### Patch Changes 149 | 150 | - 95e6d25: add cypherLanguage & various search/cursor options, misc improvements 151 | 152 | ## 1.0.0-next.11 153 | 154 | ### Patch Changes 155 | 156 | - 42dc131: fix position/selection bug, add search & indentUnit options 157 | 158 | ## 1.0.0-next.10 159 | 160 | ### Patch Changes 161 | 162 | - 4a8e102: tooltipAbsolute default to true, fix tab key bugs 163 | 164 | ## 1.0.0-next.9 165 | 166 | ### Patch Changes 167 | 168 | - b5ca4c5: rename indentWithTab -> tabKey, fix tab with autocomplete 169 | 170 | ## 1.0.0-next.8 171 | 172 | ### Patch Changes 173 | 174 | - 95e70e0: add tooltipAbsolute option / prop 175 | 176 | ## 1.0.0-next.7 177 | 178 | ### Patch Changes 179 | 180 | - d925e37: fix default application bug on editor creation 181 | 182 | ## 1.0.0-next.6 183 | 184 | ### Patch Changes 185 | 186 | - a2750e5: add js theme override to remove focused outline 187 | 188 | ## 1.0.0-next.5 189 | 190 | ### Patch Changes 191 | 192 | - de33476: Add indentWithTab prop / option 193 | 194 | ## 1.0.0-next.4 195 | 196 | ### Patch Changes 197 | 198 | - de36649: Use escaped Cypher when needed in the auto-completions 199 | 200 | ## 1.0.0-next.3 201 | 202 | ### Patch Changes 203 | 204 | - 48363de: add antlr4-browser package (remove fs dependency) 205 | - Updated dependencies [48363de] 206 | - @neo4j-cypher/editor-support@1.0.0-next.2 207 | 208 | ## 1.0.0-next.2 209 | 210 | ### Patch Changes 211 | 212 | - b35f29a: make sure calls to editorApi.set function apply defaults, fixup react types 213 | 214 | ## 1.0.0-next.1 215 | 216 | ### Patch Changes 217 | 218 | - 896eddf: add missing @babel/runtime dependency 219 | - Updated dependencies [896eddf] 220 | - @neo4j-cypher/editor-support@1.0.0-next.1 221 | 222 | ## 1.0.0-next.0 223 | 224 | ### Major Changes 225 | 226 | - 13f7151: Initial pre-release 227 | 228 | ### Patch Changes 229 | 230 | - Updated dependencies [13f7151] 231 | - @neo4j-cypher/editor-support@1.0.0-next.0 232 | -------------------------------------------------------------------------------- /packages/codemirror/README.md: -------------------------------------------------------------------------------- 1 | ### @neo4j-cypher/codemirror 2 | 3 | This package provides a variety of extensions to enable cypher language support in codemirror 6. 4 | 5 | This package exports those extensions, and provides a convenience method to create an editor with the following API: 6 | 7 | ```js 8 | // import { EditorView } from 'codemirror'; 9 | // import { CypherEditorSupport } from '@neo4j-cypher/editor-support'; 10 | 11 | const createCypherEditor = ( 12 | parentDOMElement, 13 | { text = "initial text here", extensions = undefined } = {} 14 | ) => { 15 | // create editor & editorSupport using given extensions, or default extensions if undefined 16 | const editor = new EditorView({ 17 | parentDOMElement, 18 | state: initialState // also contains editorSupport for use by extensions 19 | }); 20 | return { 21 | editor: EditorView, 22 | editorSupport: CypherEditorSupport 23 | }; 24 | }; 25 | ``` 26 | -------------------------------------------------------------------------------- /packages/codemirror/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@neo4j-cypher/codemirror", 3 | "description": "Cypher query language integration with CodeMirror 6 editor", 4 | "keywords": [ 5 | "cypher", 6 | "codemirror", 7 | "codemirror 6" 8 | ], 9 | "version": "1.0.3", 10 | "author": "Neo4j Inc.", 11 | "license": "Apache-2.0", 12 | "main": "./lib/codemirror.js", 13 | "module": "./es/codemirror.js", 14 | "exports": { 15 | ".": { 16 | "import": "./es/codemirror.js", 17 | "require": "./lib/codemirror.js" 18 | }, 19 | "./src/codemirror.d.ts": { 20 | "import": "./src/codemirror.d.ts" 21 | }, 22 | "./src/codemirror.js": { 23 | "import": "./src/codemirror.js" 24 | }, 25 | "./css/cypher-codemirror.css": { 26 | "import": "./css/cypher-codemirror.css", 27 | "require": "./css/cypher-codemirror.css" 28 | } 29 | }, 30 | "types": "src/codemirror.d.ts", 31 | "repository": { 32 | "type": "git", 33 | "url": "git://github.com/neo4j/cypher-editor.git" 34 | }, 35 | "bugs": { 36 | "url": "https://github.com/neo4j/cypher-editor/issues" 37 | }, 38 | "scripts": { 39 | "build-lib": "babel --config-file ../../babel.config.js --extensions \".js\" --out-dir lib ./src", 40 | "build-es": "cross-env ES=true babel --config-file ../../babel.config.js --extensions \".js\" --out-dir es ./src", 41 | "build": "npm run build-lib && npm run build-es", 42 | "clean:build": "rimraf lib && rimraf es" 43 | }, 44 | "files": [ 45 | "src/*.d.ts", 46 | "css/", 47 | "es/", 48 | "lib/", 49 | "README.md" 50 | ], 51 | "engineStrict": true, 52 | "engines": { 53 | "node": ">=16" 54 | }, 55 | "dependencies": { 56 | "@babel/runtime": "^7.20.13", 57 | "@codemirror/autocomplete": "^6.4.1", 58 | "@codemirror/commands": "^6.2.1", 59 | "@codemirror/language": "^6.6.0", 60 | "@codemirror/lint": "^6.1.0", 61 | "@codemirror/search": "^6.2.3", 62 | "@codemirror/state": "^6.2.0", 63 | "@codemirror/view": "^6.9.0", 64 | "@lezer/highlight": "^1.1.3", 65 | "@neo4j-cypher/editor-support": "1.0.2" 66 | }, 67 | "devDependencies": { 68 | "@babel/cli": "^7.20.7", 69 | "@babel/core": "^7.20.12", 70 | "@babel/plugin-proposal-class-properties": "^7.18.6", 71 | "@babel/plugin-proposal-object-rest-spread": "^7.20.7", 72 | "@babel/plugin-transform-regenerator": "^7.20.5", 73 | "@babel/plugin-transform-runtime": "^7.19.6", 74 | "@babel/preset-env": "^7.20.2" 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /packages/codemirror/src/cypher-codemirror-base.js: -------------------------------------------------------------------------------- 1 | export const THEME_LIGHT = "light"; 2 | export const THEME_DARK = "dark"; 3 | export const THEME_AUTO = "auto"; 4 | 5 | export const defaultLineNumberFormatter = (line, lineCount) => { 6 | if (lineCount === 1) { 7 | return "$"; 8 | } else { 9 | return line; 10 | } 11 | }; 12 | 13 | export const defaultAutocompleteTriggerStrings = [ 14 | ".", 15 | ":", 16 | "[]", 17 | "()", 18 | "{}", 19 | "[", 20 | "(", 21 | "{", 22 | "$" 23 | ]; 24 | 25 | export const defaultOptions = { 26 | autocomplete: true, 27 | autocompleteCloseOnBlur: true, 28 | autocompleteOpen: false, 29 | autocompleteTriggerStrings: defaultAutocompleteTriggerStrings, 30 | autofocus: true, 31 | autofocusProps: ["cursorWide", "position", "readOnly", "selection", "value"], 32 | bracketMatching: true, 33 | clearHistoryProps: ["cypherLanguage"], 34 | closeBrackets: true, 35 | cursorWide: true, 36 | cypherLanguage: true, 37 | history: true, 38 | indentUnit: " ", 39 | lineNumberFormatter: defaultLineNumberFormatter, 40 | lineNumbers: true, 41 | lineWrapping: false, 42 | lint: false, 43 | parseOnSetValue: true, 44 | placeholder: undefined, 45 | position: undefined, 46 | readOnly: false, 47 | readOnlyCursor: false, 48 | schema: undefined, 49 | search: true, 50 | searchMatches: 0, 51 | searchOpen: false, 52 | searchText: "", 53 | searchTop: false, 54 | selection: undefined, 55 | tabKey: true, 56 | theme: THEME_LIGHT, 57 | tooltipAbsolute: true, 58 | value: "", 59 | preExtensions: [], 60 | postExtensions: [] 61 | }; 62 | 63 | export const reactiveOptionKeys = [ 64 | "autocomplete", 65 | "autocompleteCloseOnBlur", 66 | "autocompleteOpen", 67 | "autocompleteTriggerStrings", 68 | "bracketMatching", 69 | "closeBrackets", 70 | "cursorWide", 71 | "cypherLanguage", 72 | // "autofocus", 73 | "history", 74 | "indentUnit", 75 | "lineNumberFormatter", 76 | "lineNumbers", 77 | "lineWrapping", 78 | "lint", 79 | "placeholder", 80 | "position", 81 | "readOnly", 82 | "readOnlyCursor", 83 | "schema", 84 | "search", 85 | "searchMatches", 86 | "searchOpen", 87 | "searchText", 88 | "searchTop", 89 | "selection", 90 | "tabKey", 91 | "theme", 92 | "tooltipAbsolute", 93 | // "parseOnSetValue", 94 | "value", 95 | "preExtensions", 96 | "postExtensions" 97 | ]; 98 | 99 | export const isNumber = (v) => 100 | v !== undefined && 101 | (typeof v === "number" || v instanceof Number) && 102 | isFinite(v); 103 | export const isInteger = (v) => isNumber(v) && v % 1 === 0; 104 | export const isObject = (v) => typeof v === "object" && v !== null; 105 | 106 | export const isAbsolutePosition = (v) => isInteger(v) && v >= 0; 107 | export const isLineColumnPosition = (v) => 108 | isObject(v) && 109 | isInteger(v.line) && 110 | v.line >= 1 && 111 | isInteger(v.column) && 112 | v.column >= 0; 113 | export const isLineColumnAbsolutePosition = (v) => 114 | isObject(v) && isInteger(v.position) && v.position >= 0; 115 | 116 | export const positionColumnNewToOld = ({ line, column, ...rest }) => ({ 117 | line, 118 | column: column - 1, 119 | ...rest 120 | }); 121 | 122 | export const positionColumnOldToNew = ({ line, column, ...rest }) => ({ 123 | line, 124 | column: column + 1, 125 | ...rest 126 | }); 127 | 128 | export const positionNewToOld = (positionValue) => 129 | isLineColumnPosition(positionValue) 130 | ? positionColumnNewToOld(positionValue) 131 | : positionValue; 132 | 133 | export const positionOldToNew = (positionValue) => 134 | isLineColumnPosition(positionValue) 135 | ? positionColumnOldToNew(positionValue) 136 | : positionValue; 137 | 138 | export const createEventHandlers = () => { 139 | const listeners = []; 140 | 141 | const off = (listener) => { 142 | const index = listeners.findIndex((l) => l === listener); 143 | if (index >= 0) { 144 | listeners.splice(index, 1); 145 | return true; 146 | } 147 | return false; 148 | }; 149 | 150 | const on = (listener) => { 151 | listeners.push(listener); 152 | return () => { 153 | off(listener); 154 | }; 155 | }; 156 | 157 | const fire = (...args) => { 158 | for (let listener of listeners) { 159 | listener(...args); 160 | } 161 | }; 162 | 163 | const count = () => { 164 | return listeners.length; 165 | }; 166 | 167 | return { on, off, listeners, fire, count }; 168 | }; 169 | -------------------------------------------------------------------------------- /packages/codemirror/src/cypher-state-definitions.js: -------------------------------------------------------------------------------- 1 | import { StateEffect, StateField } from "@codemirror/state"; 2 | import { EditorView, Decoration } from "@codemirror/view"; 3 | import { CypherEditorSupport } from "@neo4j-cypher/editor-support"; 4 | 5 | export const editorSupportField = StateField.define({ 6 | create() { 7 | return new CypherEditorSupport(); 8 | }, 9 | update(editorSupport, tr) { 10 | return editorSupport; 11 | } 12 | }); 13 | 14 | export const addTypeMarkerEffect = StateEffect.define(); 15 | export const clearTypeMarkersEffect = StateEffect.define(); 16 | 17 | export const typeMarkerField = StateField.define({ 18 | create() { 19 | return Decoration.none; 20 | }, 21 | update(typeMarkers, tr) { 22 | typeMarkers = typeMarkers.map(tr.changes); 23 | for (let e of tr.effects) { 24 | if (e.is(clearTypeMarkersEffect)) { 25 | typeMarkers = Decoration.none; 26 | } else if (e.is(addTypeMarkerEffect)) { 27 | if (e.value.from !== e.value.to) { 28 | typeMarkers = typeMarkers.update({ 29 | add: [ 30 | Decoration.mark({ class: "cm-p-" + e.value.type }).range( 31 | e.value.from, 32 | e.value.to 33 | ) 34 | ] 35 | }); 36 | } 37 | } 38 | } 39 | return typeMarkers; 40 | }, 41 | provide: (f) => EditorView.decorations.from(f) 42 | }); 43 | -------------------------------------------------------------------------------- /packages/codemirror/src/cypher.js: -------------------------------------------------------------------------------- 1 | import { CypherKeywords } from "@neo4j-cypher/editor-support"; 2 | 3 | const operators = [ 4 | ";", 5 | "(", 6 | ")", 7 | "{", 8 | "}", 9 | "[", 10 | "]", 11 | "$", 12 | ":", 13 | ".", 14 | "=", 15 | "<", 16 | ">", 17 | "+", 18 | "-", 19 | "*", 20 | "`", 21 | ",", 22 | "?", 23 | "|", 24 | "..", 25 | "+=", 26 | "<>", 27 | "!=", 28 | "<=", 29 | ">=", 30 | "/", 31 | "%", 32 | "^", 33 | "=~" 34 | ]; 35 | 36 | let curPunc; 37 | 38 | const keywordRegexes = CypherKeywords.map((w) => new RegExp(w, "i")); 39 | const lineCommentRegex = /\/\/[^\r\n]*/; 40 | const blockCommentRegex = /\/\*([\S\s]*?)\*\//; 41 | const stringRegex = /('([^'\\]|\\.)*'|"([^"\\]|\\.)*")/; 42 | const stringStartRegex = /('([^'\\]|\\.)*|"([^"\\]|\\.)*)/; // match just opened and not closed string as string 43 | const integerRegex = /[+-]?(([1-9][0-9]+)|([0-9]))/; 44 | const decimalRegex = /[+-]?(([1-9][0-9]+)|([0-9]))\.[0-9]+/; 45 | 46 | const tokenBase = (stream) => { 47 | if (stream.match(lineCommentRegex) || stream.match(blockCommentRegex)) { 48 | return "comment"; 49 | } else if (stream.match(stringRegex)) { 50 | return "string"; 51 | } else if (stream.match(integerRegex)) { 52 | return "number"; 53 | } else if (stream.match(decimalRegex)) { 54 | return "number"; 55 | } else if (operators.find((o) => stream.match(o))) { 56 | return "operator"; 57 | } else if (keywordRegexes.find((k) => stream.match(k))) { 58 | return "keyword"; 59 | } else if (stream.match(stringStartRegex)) { 60 | return "string"; 61 | } 62 | 63 | stream.next(); 64 | stream.eatWhile(/[_\p{Letter}\p{Emoji}\d]/u); 65 | 66 | return "variable"; 67 | }; 68 | const pushContext = (state, type, col) => { 69 | state.context = { 70 | prev: state.context, 71 | indent: state.indent, 72 | col, 73 | type 74 | }; 75 | return state.context; 76 | }; 77 | const popContext = (state) => { 78 | state.indent = state.context.indent; 79 | state.context = state.context.prev; 80 | return state.context; 81 | }; 82 | 83 | export const cypher = { 84 | startState() { 85 | return { 86 | tokenize: tokenBase, 87 | context: null, 88 | indent: 0, 89 | col: 0 90 | }; 91 | }, 92 | token(stream, state) { 93 | if (stream.sol()) { 94 | if (state.context && state.context.align == null) { 95 | state.context.align = false; 96 | } 97 | state.indent = stream.indentation(); 98 | } 99 | if (stream.eatSpace()) { 100 | return null; 101 | } 102 | const style = state.tokenize(stream, state); 103 | if ( 104 | style !== "comment" && 105 | state.context && 106 | state.context.align == null && 107 | state.context.type !== "pattern" 108 | ) { 109 | state.context.align = true; 110 | } 111 | if (curPunc === "(") { 112 | pushContext(state, ")", stream.column()); 113 | } else if (curPunc === "[") { 114 | pushContext(state, "]", stream.column()); 115 | } else if (curPunc === "{") { 116 | pushContext(state, "}", stream.column()); 117 | } else if (/[\]})]/.test(curPunc)) { 118 | while (state.context && state.context.type === "pattern") { 119 | popContext(state); 120 | } 121 | if (state.context && curPunc === state.context.type) { 122 | popContext(state); 123 | } 124 | } else if ( 125 | curPunc === "." && 126 | state.context && 127 | state.context.type === "pattern" 128 | ) { 129 | popContext(state); 130 | } else if (/atom|string|variable/.test(style) && state.context) { 131 | if (/[}\]]/.test(state.context.type)) { 132 | pushContext(state, "pattern", stream.column()); 133 | } else if (state.context.type === "pattern" && !state.context.align) { 134 | state.context.align = true; 135 | state.context.col = stream.column(); 136 | } 137 | } 138 | return style; 139 | }, 140 | indent: (state, textAfter, cx) => { 141 | const firstChar = textAfter && textAfter.charAt(0); 142 | let context = state.context; 143 | if (/[\]}]/.test(firstChar)) { 144 | while (context && context.type === "pattern") { 145 | context = context.prev; 146 | } 147 | } 148 | const closing = context && firstChar === context.type; 149 | if (!context) return 0; 150 | if (context.type === "keywords") return null; // return CodeMirror.commands.newlineAndIndent; 151 | if (context.align) return context.col + (closing ? 0 : 1); 152 | return context.indent + (closing ? 0 : cx.unit); 153 | }, 154 | languageData: { 155 | commentTokens: { line: "//", block: { open: "/*", close: "*/" } } 156 | } 157 | }; 158 | -------------------------------------------------------------------------------- /packages/editor-support/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @neo4j-cypher/editor-support 2 | 3 | ## 1.0.2 4 | 5 | ### Patch Changes 6 | 7 | - bdae809: Update `exports` field to fix issue with TypeScript `Bundler` module resolution mode 8 | 9 | ## 1.0.1 10 | 11 | ### Patch Changes 12 | 13 | - 54698be: Export util functions and types for usage in Neo4j Browser 14 | 15 | ## 1.0.0 16 | 17 | ### Major Changes 18 | 19 | - 13f7151: Initial pre-release 20 | 21 | ### Patch Changes 22 | 23 | - 6e6269f: remove use of constructor.name in editor-support package 24 | - 896eddf: add missing @babel/runtime dependency 25 | - 8ba2deb: Exit pre-release mode 26 | - 8549a61: Apply workaround for node 18.14.0 support 27 | - 48363de: add antlr4-browser package (remove fs dependency) 28 | - acd35e1: Update repo url after move 29 | - 45a590b: Change license from GPL-3.0 to Apache-2.0 30 | - 91cb80a: Fix module exports + add shallow comparision on schema updates 31 | - Updated dependencies [896eddf] 32 | - Updated dependencies [8ba2deb] 33 | - Updated dependencies [8549a61] 34 | - Updated dependencies [48363de] 35 | - Updated dependencies [acd35e1] 36 | - Updated dependencies [45a590b] 37 | - Updated dependencies [91cb80a] 38 | - Updated dependencies [13f7151] 39 | - @neo4j-cypher/antlr4@1.0.0 40 | 41 | ## 1.0.0-next.6 42 | 43 | ### Patch Changes 44 | 45 | - 8549a61: Apply workaround for node 18.14.0 support 46 | - Updated dependencies [8549a61] 47 | - @neo4j-cypher/antlr4@1.0.0-next.5 48 | 49 | ## 1.0.0-next.5 50 | 51 | ### Patch Changes 52 | 53 | - acd35e1: Update repo url after move 54 | - 45a590b: Change license from GPL-3.0 to Apache-2.0 55 | - Updated dependencies [acd35e1] 56 | - Updated dependencies [45a590b] 57 | - @neo4j-cypher/antlr4@1.0.0-next.4 58 | 59 | ## 1.0.0-next.4 60 | 61 | ### Patch Changes 62 | 63 | - 91cb80a: Fix module exports + add shallow comparision on schema updates 64 | - Updated dependencies [91cb80a] 65 | - @neo4j-cypher/antlr4@1.0.0-next.3 66 | 67 | ## 1.0.0-next.3 68 | 69 | ### Patch Changes 70 | 71 | - 6e6269f: remove use of constructor.name in editor-support package 72 | 73 | ## 1.0.0-next.2 74 | 75 | ### Patch Changes 76 | 77 | - 48363de: add antlr4-browser package (remove fs dependency) 78 | - Updated dependencies [48363de] 79 | - @neo4j-cypher/antlr4@1.0.0-next.2 80 | 81 | ## 1.0.0-next.1 82 | 83 | ### Patch Changes 84 | 85 | - 896eddf: add missing @babel/runtime dependency 86 | - Updated dependencies [896eddf] 87 | - @neo4j-cypher/antlr4@1.0.0-next.1 88 | 89 | ## 1.0.0-next.0 90 | 91 | ### Major Changes 92 | 93 | - 13f7151: Initial pre-release 94 | 95 | ### Patch Changes 96 | 97 | - Updated dependencies [13f7151] 98 | - @neo4j-cypher/antlr4@1.0.0-next.0 99 | -------------------------------------------------------------------------------- /packages/editor-support/README.md: -------------------------------------------------------------------------------- 1 | ### @neo4j-cypher/editor-support 2 | 3 | This package powers linting, autocompletion, and syntax highlighting for the cypher query language. 4 | 5 | It is used by packages that support codemirror 5, codemirror 6, and monaco. 6 | 7 | The main export of this package is the `CypherEditorSupport` class. 8 | 9 | More docs coming soon... 10 | -------------------------------------------------------------------------------- /packages/editor-support/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@neo4j-cypher/editor-support", 3 | "description": "Core functionality to support Cypher integration into editors", 4 | "keywords": [ 5 | "cypher" 6 | ], 7 | "version": "1.0.2", 8 | "author": "Neo4j Inc.", 9 | "license": "Apache-2.0", 10 | "main": "lib/editor-support.js", 11 | "module": "es/editor-support.js", 12 | "exports": { 13 | ".": { 14 | "import": "./es/editor-support.js", 15 | "require": "./lib/editor-support.js", 16 | "types": "./src/editor-support.d.ts" 17 | }, 18 | "./src/editor-support.d.ts": { 19 | "import": "./src/editor-support.d.ts" 20 | }, 21 | "./src/editor-support.js": { 22 | "import": "./src/editor-support.js" 23 | } 24 | }, 25 | "types": "src/editor-support.d.ts", 26 | "repository": { 27 | "type": "git", 28 | "url": "git://github.com/neo4j/cypher-editor.git" 29 | }, 30 | "bugs": { 31 | "url": "https://github.com/neo4j/cypher-editor/issues" 32 | }, 33 | "scripts": { 34 | "build-lib": "babel --config-file ../../babel.config.js --extensions \".js\" --out-dir lib ./src", 35 | "build-es": "cross-env ES=true babel --config-file ../../babel.config.js --extensions \".js\" --out-dir es ./src", 36 | "build": "npm run build-lib && npm run build-es", 37 | "clean:build": "rimraf lib && rimraf es" 38 | }, 39 | "files": [ 40 | "src/*.d.ts", 41 | "es/", 42 | "lib/", 43 | "README.md" 44 | ], 45 | "engineStrict": true, 46 | "engines": { 47 | "node": ">=14.0.0" 48 | }, 49 | "dependencies": { 50 | "@babel/runtime": "^7.20.13", 51 | "@neo4j-cypher/antlr4": "1.0.0", 52 | "fuse.js": "^6.6.2", 53 | "lodash.find": "^4.6.0", 54 | "lodash.includes": "^4.3.0" 55 | }, 56 | "devDependencies": { 57 | "@babel/cli": "^7.20.7", 58 | "@babel/core": "^7.20.12", 59 | "@babel/plugin-proposal-class-properties": "^7.18.6", 60 | "@babel/plugin-proposal-object-rest-spread": "^7.20.7", 61 | "@babel/plugin-transform-regenerator": "^7.20.5", 62 | "@babel/plugin-transform-runtime": "^7.19.6", 63 | "@babel/preset-env": "^7.20.2" 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /packages/editor-support/src/completion/CompletionTypeResolver.js: -------------------------------------------------------------------------------- 1 | import * as CompletionTypes from "./CompletionTypes"; 2 | import * as rules from "./rules"; 3 | 4 | // Rules are sorted starting with specific ones, and finishing with more generic ones. 5 | const orderedCompletionRules = [ 6 | rules.ruleNoop, 7 | rules.ruleVariableInExpressionPossibleFunction, 8 | rules.ruleLiteralEntry, 9 | rules.rulePropInMapLiteral, 10 | rules.ruleParamStartsWithDollar, 11 | rules.ruleSpecificParent, 12 | rules.ruleNodePattern, 13 | rules.ruleRelationshipPattern, 14 | rules.ruleProcedureOutputsInCallClause, 15 | rules.ruleCallClauseBeginning, 16 | rules.ruleConsoleCommandSubcommands, 17 | rules.rulePropertyLookup, 18 | rules.rulePossibleKeyword 19 | ]; 20 | 21 | function evaluateRules(element) { 22 | for (let i = 0; i < orderedCompletionRules.length; i += 1) { 23 | const rule = orderedCompletionRules[i]; 24 | const types = rule(element); 25 | if (types.length > 0) { 26 | return types; 27 | } 28 | } 29 | 30 | return []; 31 | } 32 | 33 | export class CompletionTypeResolver { 34 | static getTypes(element) { 35 | // If element is null, then no types 36 | if (element == null) { 37 | return { 38 | found: false, 39 | types: CompletionTypes.ALL 40 | }; 41 | } 42 | 43 | // Retrieve types from rules 44 | const types = evaluateRules(element); 45 | if (types.length > 0) { 46 | return { 47 | found: true, 48 | types 49 | }; 50 | } 51 | 52 | // If no types found, then no types 53 | return { 54 | found: false, 55 | types: CompletionTypes.ALL 56 | }; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /packages/editor-support/src/completion/CompletionTypes.js: -------------------------------------------------------------------------------- 1 | export const KEYWORD = "keyword"; 2 | export const LABEL = "label"; 3 | export const VARIABLE = "variable"; 4 | export const PARAMETER = "parameter"; 5 | export const PROPERTY_KEY = "propertyKey"; 6 | export const RELATIONSHIP_TYPE = "relationshipType"; 7 | export const FUNCTION_NAME = "function"; 8 | export const PROCEDURE_NAME = "procedure"; 9 | export const CONSOLE_COMMAND_NAME = "consoleCommand"; 10 | export const CONSOLE_COMMAND_SUBCOMMAND = "consoleCommandSubcommand"; 11 | export const PROCEDURE_OUTPUT = "procedureOutput"; 12 | 13 | // Return no autocompletion 14 | export const NOOP = "noop"; 15 | 16 | // Default 17 | export const ALL = [ 18 | VARIABLE, 19 | PARAMETER, 20 | PROPERTY_KEY, 21 | FUNCTION_NAME, 22 | KEYWORD 23 | ].map((type) => ({ type })); 24 | -------------------------------------------------------------------------------- /packages/editor-support/src/completion/rules/index.js: -------------------------------------------------------------------------------- 1 | import ruleSpecificParent from "./ruleCheckParent"; 2 | import ruleVariableInExpressionPossibleFunction from "./ruleVariableInExpressionPossibleFunction"; 3 | import ruleProcedureOutputsInCallClause from "./ruleProcedureOutputsInCallClause"; 4 | import ruleCallClauseBeginning from "./ruleCallClauseBeginning"; 5 | import rulePossibleKeyword from "./rulePossibleKeyword"; 6 | import ruleRelationshipPattern from "./ruleRelationshipPattern"; 7 | import ruleNodePattern from "./ruleNodePattern"; 8 | import rulePropertyLookup from "./rulePropertyLookup"; 9 | import rulePropInMapLiteral from "./rulePropInMapLiteral"; 10 | import ruleLiteralEntry from "./ruleLiteralEntry"; 11 | import ruleConsoleCommandSubcommands from "./ruleConsoleCommandSubcommands"; 12 | import ruleNoop from "./ruleNoop"; 13 | import ruleParamStartsWithDollar from "./ruleParamStartsWithDollar"; 14 | 15 | export { 16 | ruleSpecificParent, 17 | ruleVariableInExpressionPossibleFunction, 18 | ruleProcedureOutputsInCallClause, 19 | ruleCallClauseBeginning, 20 | rulePossibleKeyword, 21 | ruleRelationshipPattern, 22 | ruleNodePattern, 23 | rulePropertyLookup, 24 | rulePropInMapLiteral, 25 | ruleLiteralEntry, 26 | ruleConsoleCommandSubcommands, 27 | ruleNoop, 28 | ruleParamStartsWithDollar 29 | }; 30 | -------------------------------------------------------------------------------- /packages/editor-support/src/completion/rules/ruleCallClauseBeginning.js: -------------------------------------------------------------------------------- 1 | import * as CypherTypes from "../../lang/CypherTypes"; 2 | import * as CompletionTypes from "../CompletionTypes"; 3 | 4 | // If we are in call rule, and element is second child of call return procedure types 5 | export default (element) => { 6 | const parent = element.parentCtx; 7 | if (!parent) { 8 | return []; 9 | } 10 | 11 | if (parent instanceof CypherTypes.CALL_CONTEXT) { 12 | const secondChild = parent.getChild(1); 13 | if (secondChild === element) { 14 | return [{ type: CompletionTypes.PROCEDURE_NAME }]; 15 | } 16 | } 17 | 18 | return []; 19 | }; 20 | -------------------------------------------------------------------------------- /packages/editor-support/src/completion/rules/ruleCheckParent.js: -------------------------------------------------------------------------------- 1 | import * as CypherTypes from "../../lang/CypherTypes"; 2 | import * as CompletionTypes from "../CompletionTypes"; 3 | import { TreeUtils } from "../../util/TreeUtils"; 4 | 5 | const childToParentTypeMapping = new Map(); 6 | childToParentTypeMapping.set(CypherTypes.VARIABLE_CONTEXT, [ 7 | { type: CompletionTypes.VARIABLE } 8 | ]); 9 | childToParentTypeMapping.set(CypherTypes.PARAMETER_NAME_CONTEXT, [ 10 | { type: CompletionTypes.PARAMETER } 11 | ]); 12 | childToParentTypeMapping.set(CypherTypes.PROPERTY_KEY_NAME_CONTEXT, [ 13 | { type: CompletionTypes.PROPERTY_KEY } 14 | ]); 15 | childToParentTypeMapping.set(CypherTypes.FUNCTION_NAME_CONTEXT, [ 16 | { type: CompletionTypes.FUNCTION_NAME } 17 | ]); 18 | childToParentTypeMapping.set(CypherTypes.PROCEDURE_NAME_CONTEXT, [ 19 | { type: CompletionTypes.PROCEDURE_NAME } 20 | ]); 21 | childToParentTypeMapping.set(CypherTypes.NODE_LABEL_CONTEXT, [ 22 | { type: CompletionTypes.LABEL } 23 | ]); 24 | childToParentTypeMapping.set(CypherTypes.RELATIONSHIP_TYPE_CONTEXT, [ 25 | { type: CompletionTypes.RELATIONSHIP_TYPE } 26 | ]); 27 | childToParentTypeMapping.set( 28 | CypherTypes.RELATIONSHIP_TYPE_OPTIONAL_COLON_CONTEXT, 29 | [{ type: CompletionTypes.RELATIONSHIP_TYPE }] 30 | ); 31 | childToParentTypeMapping.set(CypherTypes.CONSOLE_COMMAND_NAME_CONTEXT, [ 32 | { type: CompletionTypes.CONSOLE_COMMAND_NAME } 33 | ]); 34 | childToParentTypeMapping.set(CypherTypes.NODE_LABELS_CONTEXT, [ 35 | { type: CompletionTypes.LABEL } 36 | ]); 37 | childToParentTypeMapping.set(CypherTypes.RELATIONSHIP_TYPES_CONTEXT, [ 38 | { type: CompletionTypes.RELATIONSHIP_TYPE } 39 | ]); 40 | 41 | // Check that element is inside specific parent context 42 | export default (element) => { 43 | const parent = TreeUtils.findAnyParent( 44 | element, 45 | Array.from(childToParentTypeMapping.keys()) 46 | ); 47 | return parent != null ? childToParentTypeMapping.get(parent.constructor) : []; 48 | }; 49 | -------------------------------------------------------------------------------- /packages/editor-support/src/completion/rules/ruleConsoleCommandSubcommands.js: -------------------------------------------------------------------------------- 1 | import * as CypherTypes from "../../lang/CypherTypes"; 2 | import * as CompletionTypes from "../CompletionTypes"; 3 | import { TreeUtils } from "../../util/TreeUtils"; 4 | 5 | // If we are in console command, and not in console command name, return path 6 | export default (element) => { 7 | let consoleCommand = TreeUtils.findParent( 8 | element.parentCtx, 9 | CypherTypes.CONSOLE_COMMAND_CONTEXT 10 | ); 11 | let isAtTheEndOfConsoleCommand = false; 12 | if (!consoleCommand) { 13 | // We are not in console command. But maybe we are on a space at the end of console command? 14 | // If first child of parent contains console command 15 | // and second child is our current element 16 | // then we are at the space at the end of console command 17 | const parent = element.parentCtx; 18 | const child1 = TreeUtils.findChild( 19 | parent.children[0], 20 | CypherTypes.CONSOLE_COMMAND_CONTEXT 21 | ); 22 | const child2 = parent.children[1]; 23 | if (child1 && child2 && child2 === element) { 24 | consoleCommand = child1; 25 | isAtTheEndOfConsoleCommand = true; 26 | } else { 27 | return []; 28 | } 29 | } 30 | 31 | // Find current parameter or space 32 | const currentElement = 33 | TreeUtils.findParent( 34 | element, 35 | CypherTypes.CONSOLE_COMMAND_PARAMETER_CONTEXT 36 | ) || element; 37 | 38 | const path = []; 39 | let currentElementInParameter = false; 40 | 41 | // Iterate over parameters, and stop when we found current one. 42 | for (let i = 0; i < consoleCommand.children.length; i += 1) { 43 | const child = consoleCommand.children[i]; 44 | if (child instanceof CypherTypes.CONSOLE_COMMAND_NAME_CONTEXT) { 45 | path.push(child.getText()); 46 | } 47 | if (child instanceof CypherTypes.CONSOLE_COMMAND_PARAMETERS_CONTEXT) { 48 | for (let j = 0; j < child.children.length; j += 1) { 49 | const parameterChild = child.children[j]; 50 | if ( 51 | parameterChild instanceof 52 | CypherTypes.CONSOLE_COMMAND_PARAMETER_CONTEXT 53 | ) { 54 | path.push(parameterChild.getText()); 55 | currentElementInParameter = true; 56 | } else { 57 | currentElementInParameter = false; 58 | } 59 | if (parameterChild === currentElement) { 60 | break; 61 | } 62 | } 63 | } 64 | } 65 | 66 | // If we are at the end of console command, nothing to filter. 67 | let filterLastElement; 68 | if (isAtTheEndOfConsoleCommand) { 69 | filterLastElement = false; 70 | } else { 71 | // If we are in parameter, filter, otherwise not 72 | filterLastElement = currentElementInParameter; 73 | } 74 | 75 | return [ 76 | { 77 | type: CompletionTypes.CONSOLE_COMMAND_SUBCOMMAND, 78 | path, 79 | filterLastElement 80 | } 81 | ]; 82 | }; 83 | -------------------------------------------------------------------------------- /packages/editor-support/src/completion/rules/ruleLiteralEntry.js: -------------------------------------------------------------------------------- 1 | import * as CypherTypes from "../../lang/CypherTypes"; 2 | import * as CompletionTypes from "../CompletionTypes"; 3 | import { TreeUtils } from "../../util/TreeUtils"; 4 | 5 | export default (element) => { 6 | const literalEntry = TreeUtils.findParent( 7 | element, 8 | CypherTypes.MAP_LITERAL_ENTRY 9 | ); 10 | if (!literalEntry) { 11 | return []; 12 | } 13 | const doubleDots = literalEntry.getChild(1); 14 | const space = literalEntry.getChild(2); 15 | if (doubleDots === element || space === element) { 16 | return CompletionTypes.ALL; 17 | } 18 | return []; 19 | }; 20 | -------------------------------------------------------------------------------- /packages/editor-support/src/completion/rules/ruleNodePattern.js: -------------------------------------------------------------------------------- 1 | import * as CypherTypes from "../../lang/CypherTypes"; 2 | import * as CompletionTypes from "../CompletionTypes"; 3 | 4 | // If we are in relationship pattern then return variables and types 5 | export default (element) => { 6 | const parent = element.getParent ? element.getParent() : null; 7 | const text = element.getText(); 8 | // Special case. We are at the beginning of first node pattern. 9 | if (parent) { 10 | if (parent instanceof CypherTypes.PATTERN_ELEMENT_CONTEXT && text === "(") { 11 | return [ 12 | { type: CompletionTypes.VARIABLE }, 13 | { type: CompletionTypes.LABEL } 14 | ]; 15 | } 16 | 17 | if (parent instanceof CypherTypes.NODE_PATTERN_CONTEXT) { 18 | // We are at the begining of node pattern 19 | if (text === "(") { 20 | return [ 21 | { type: CompletionTypes.VARIABLE }, 22 | { type: CompletionTypes.LABEL } 23 | ]; 24 | } 25 | if (text === ":") { 26 | return [{ type: CompletionTypes.LABEL }]; 27 | } 28 | } 29 | } 30 | 31 | return []; 32 | }; 33 | -------------------------------------------------------------------------------- /packages/editor-support/src/completion/rules/ruleNoop.js: -------------------------------------------------------------------------------- 1 | import * as CypherTypes from "../../lang/CypherTypes"; 2 | import * as CompletionTypes from "../CompletionTypes"; 3 | 4 | // Specify place where no autocompletion should be triggered 5 | export default (element) => { 6 | if (element instanceof CypherTypes.STRING_LITERAL_CONTEXT) { 7 | return [{ type: CompletionTypes.NOOP }]; 8 | } 9 | 10 | return []; 11 | }; 12 | -------------------------------------------------------------------------------- /packages/editor-support/src/completion/rules/ruleParamStartsWithDollar.js: -------------------------------------------------------------------------------- 1 | import * as CompletionTypes from "../CompletionTypes"; 2 | 3 | export default (element) => { 4 | const text = element.getText(); 5 | if (text === "$") { 6 | return [{ type: CompletionTypes.PARAMETER }]; 7 | } 8 | return []; 9 | }; 10 | -------------------------------------------------------------------------------- /packages/editor-support/src/completion/rules/rulePossibleKeyword.js: -------------------------------------------------------------------------------- 1 | import _includes from "lodash.includes"; 2 | import * as CompletionTypes from "../CompletionTypes"; 3 | import CypherKeywords from "../../lang/CypherKeywords"; 4 | 5 | // If any of the keywords contains element text, return ALL 6 | export default (element) => { 7 | const text = element.getText().toLowerCase(); 8 | if ( 9 | CypherKeywords.find((keyword) => _includes(keyword.toLowerCase(), text)) 10 | ) { 11 | return CompletionTypes.ALL; 12 | } 13 | return []; 14 | }; 15 | -------------------------------------------------------------------------------- /packages/editor-support/src/completion/rules/ruleProcedureOutputsInCallClause.js: -------------------------------------------------------------------------------- 1 | import * as CypherTypes from "../../lang/CypherTypes"; 2 | import * as CompletionTypes from "../CompletionTypes"; 3 | import { TreeUtils } from "../../util/TreeUtils"; 4 | 5 | // Return procedure output completion if we are inside procedure 6 | export default (element) => { 7 | const call = TreeUtils.findAnyParent(element, [CypherTypes.CALL_CONTEXT]); 8 | if (call != null) { 9 | const procedure = TreeUtils.findChild( 10 | call, 11 | CypherTypes.PROCEDURE_NAME_CONTEXT 12 | ); 13 | const resultOutput = TreeUtils.findAnyParent(element, [ 14 | CypherTypes.PROCEDURE_RESULTS_CONTEXT 15 | ]); 16 | 17 | if (procedure == null || resultOutput == null) { 18 | return []; 19 | } 20 | 21 | return [ 22 | { type: CompletionTypes.PROCEDURE_OUTPUT, name: procedure.getText() } 23 | ]; 24 | } 25 | return []; 26 | }; 27 | -------------------------------------------------------------------------------- /packages/editor-support/src/completion/rules/rulePropInMapLiteral.js: -------------------------------------------------------------------------------- 1 | import * as CypherTypes from "../../lang/CypherTypes"; 2 | import * as CompletionTypes from "../CompletionTypes"; 3 | import { TreeUtils } from "../../util/TreeUtils"; 4 | 5 | export default (element) => { 6 | const mapLiteralContext = TreeUtils.findParent( 7 | element, 8 | CypherTypes.MAP_LITERAL_CONTEXT 9 | ); 10 | const propertiesContext = TreeUtils.findParent( 11 | element, 12 | CypherTypes.PROPERTIES_CONTEXT 13 | ); 14 | 15 | if (mapLiteralContext) { 16 | const text = element.getText(); 17 | if (text === "}") { 18 | return []; 19 | } 20 | return [{ type: CompletionTypes.PROPERTY_KEY }]; 21 | } 22 | 23 | if (propertiesContext) { 24 | const text = element.getText(); 25 | if (text === "}") { 26 | return []; 27 | } 28 | if (/\s+/.test(text)) { 29 | return []; 30 | } 31 | return [ 32 | { type: CompletionTypes.PROPERTY_KEY }, 33 | { type: CompletionTypes.PARAMETER } 34 | ]; 35 | } 36 | 37 | return []; 38 | }; 39 | -------------------------------------------------------------------------------- /packages/editor-support/src/completion/rules/rulePropertyLookup.js: -------------------------------------------------------------------------------- 1 | import * as CypherTypes from "../../lang/CypherTypes"; 2 | import * as CompletionTypes from "../CompletionTypes"; 3 | 4 | export default (element) => { 5 | const lookupContext = element.getParent(); 6 | const text = element.getText(); 7 | 8 | if (lookupContext) { 9 | if ( 10 | lookupContext instanceof CypherTypes.PROPERTY_LOOKUP_CONTEXT && 11 | text === "." 12 | ) { 13 | return [{ type: CompletionTypes.PROPERTY_KEY }]; 14 | } 15 | } 16 | return []; 17 | }; 18 | -------------------------------------------------------------------------------- /packages/editor-support/src/completion/rules/ruleRelationshipPattern.js: -------------------------------------------------------------------------------- 1 | import * as CypherTypes from "../../lang/CypherTypes"; 2 | import * as CompletionTypes from "../CompletionTypes"; 3 | import { TreeUtils } from "../../util/TreeUtils"; 4 | 5 | // If we are in relationship pattern then return variables and types 6 | export default (element) => { 7 | const parent = TreeUtils.findParent( 8 | element, 9 | CypherTypes.RELATIONSHIP_PATTERN_CONTEXT 10 | ); 11 | if (parent) { 12 | // We are at the beginning, so allow variables too 13 | if (element.getText() === "[") { 14 | return [ 15 | { type: CompletionTypes.VARIABLE }, 16 | { type: CompletionTypes.RELATIONSHIP_TYPE } 17 | ]; 18 | } 19 | // We are at the end, fail and allow algorithm to get back by 1 char 20 | if (element.getText() === "]") { 21 | return []; 22 | } 23 | } 24 | return []; 25 | }; 26 | -------------------------------------------------------------------------------- /packages/editor-support/src/completion/rules/ruleVariableInExpressionPossibleFunction.js: -------------------------------------------------------------------------------- 1 | import * as CypherTypes from "../../lang/CypherTypes"; 2 | import * as CompletionTypes from "../CompletionTypes"; 3 | import { TreeUtils } from "../../util/TreeUtils"; 4 | 5 | // If variable is inside expression context then it might be both variable and function 6 | export default (element) => { 7 | const variable = TreeUtils.findAnyParent(element, [ 8 | CypherTypes.VARIABLE_CONTEXT 9 | ]); 10 | const expression = TreeUtils.findAnyParent(variable, [ 11 | CypherTypes.EXPRESSION_CONTEXT 12 | ]); 13 | return variable != null && expression != null 14 | ? [ 15 | { type: CompletionTypes.VARIABLE }, 16 | { type: CompletionTypes.FUNCTION_NAME } 17 | ] 18 | : []; 19 | }; 20 | -------------------------------------------------------------------------------- /packages/editor-support/src/editor-support.d.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Cypher language support package using an antlr4 grammar 3 | * 4 | * @remarks 5 | * 6 | * This package provides cypher query parsing using an antlr4 grammar. 7 | * 8 | * It is mostly unchanged from the original implementation. 9 | * 10 | * It provides capabilities for cypher query syntax highlighting and 11 | * and autocompletion suggestions. 12 | * 13 | * @packageDocumentation 14 | */ 15 | 16 | /** 17 | * The editor support library has its own representation of editor positions 18 | */ 19 | export interface EditorSupportPosition { 20 | /** 21 | * The 1 based line number 22 | * The 0 based column number 23 | */ 24 | line: number; 25 | column: number; 26 | } 27 | 28 | /** 29 | * EditorSupportCompletionItem 30 | */ 31 | export interface EditorSupportCompletionItem { 32 | type: CompletionType; 33 | view: string; 34 | content: string; 35 | postfix: null; 36 | } 37 | 38 | /** 39 | * A console command, these are typically prefixed with `:` like `:help` 40 | */ 41 | export interface ConsoleCommand { 42 | name: string; 43 | description?: string; 44 | commands?: ConsoleCommand[]; 45 | } 46 | 47 | /** 48 | * A function provided by the graph database 49 | */ 50 | export interface FunctionSchema { 51 | name: string; 52 | signature: string; 53 | } 54 | 55 | /** 56 | * A procedure provided by the graph database 57 | */ 58 | export interface ProcedureSchema { 59 | name: string; 60 | signature: string; 61 | returnItems: FunctionSchema[]; 62 | } 63 | 64 | /** 65 | * The editor support schema contains information about a graph database 66 | * that enables advanced autocompletion & syntax highlighting. 67 | */ 68 | export interface EditorSupportSchema { 69 | /** 70 | * The list of labels in the graph database 71 | */ 72 | labels?: string[]; 73 | /** 74 | * The list of relationship types in the graph database 75 | */ 76 | relationshipTypes?: string[]; 77 | /** 78 | * The list of property keys in the graph database 79 | */ 80 | propertyKeys?: string[]; 81 | /** 82 | * The list of functions provided the graph database 83 | */ 84 | functions?: FunctionSchema[]; 85 | /** 86 | * The list of procedures provided the graph database 87 | */ 88 | procedures?: ProcedureSchema[]; 89 | /** 90 | * The list of console commands 91 | */ 92 | consoleCommands?: ConsoleCommand[]; 93 | /** 94 | * The list of parameters 95 | */ 96 | parameters?: string[]; 97 | } 98 | 99 | /** 100 | * Instances of this class are used to encapsulate the parsed cypher tree for the antlr4 grammar 101 | */ 102 | export class CypherEditorSupport { 103 | constructor(input: string); 104 | getCompletion( 105 | line: number, 106 | column: number, 107 | doFilter?: boolean 108 | ): { 109 | from: EditorSupportPosition; 110 | to: EditorSupportPosition; 111 | items: EditorSupportCompletionItem[]; 112 | }; 113 | setSchema(schema: EditorSupportSchema): void; 114 | update(input: string): void; 115 | } 116 | 117 | /** 118 | * All autocomplete options have a CompletionType 119 | */ 120 | export type CompletionType = 121 | | "keyword" 122 | | "label" 123 | | "variable" 124 | | "parameter" 125 | | "propertyKey" 126 | | "relationshipType" 127 | | "function" 128 | | "procedure" 129 | | "consoleCommand" 130 | | "consoleCommandSubcommand" 131 | | "procedureOutput" 132 | | "noop"; 133 | 134 | import { Lexer } from "@neo4j-cypher/antlr4"; 135 | /** 136 | * The CypherLexer class generated by antlr4 137 | */ 138 | export class CypherLexer extends Lexer { 139 | constructor(input: string); 140 | channelNames: string[]; 141 | modeNames: string[]; 142 | literalNames: string[]; 143 | symbolicNames: string[]; 144 | ruleNames: string[]; 145 | grammarFileName: string; 146 | } 147 | 148 | /** 149 | * Helper function to instanciate a CypherLexer 150 | */ 151 | declare function createCypherLexer(input: string): CypherLexer; 152 | 153 | /** 154 | * Helper function to parse a cypher query 155 | */ 156 | declare function parse(input: string): { 157 | referencesListener: { 158 | queriesAndCommands: QueryOrCommand[]; 159 | }; 160 | }; 161 | declare interface QueryOrCommand { 162 | getText: () => string; 163 | start: EditorSupportPosition; 164 | stop: EditorSupportPosition; 165 | cypherConsoleCommandName: () => { getText: () => string }; 166 | } 167 | -------------------------------------------------------------------------------- /packages/editor-support/src/editor-support.js: -------------------------------------------------------------------------------- 1 | import { CypherEditorSupport } from "./CypherEditorSupport"; 2 | import { TreeUtils } from "./util/TreeUtils"; 3 | import { parse } from "./util/parse"; 4 | import * as CypherTypes from "./lang/CypherTypes"; 5 | import CypherKeywords from "./lang/CypherKeywords"; 6 | import { ReferencesProvider } from "./references/ReferencesProvider"; 7 | import { createCypherLexer } from "./util/createCypherLexer"; 8 | import { ErrorListener } from "./errors/ErrorListener"; 9 | 10 | export { 11 | createCypherLexer, 12 | CypherEditorSupport, 13 | CypherTypes, 14 | CypherKeywords, 15 | TreeUtils, 16 | parse, 17 | ReferencesProvider, 18 | ErrorListener 19 | }; 20 | -------------------------------------------------------------------------------- /packages/editor-support/src/errors/ErrorListener.js: -------------------------------------------------------------------------------- 1 | import antlr4 from "@neo4j-cypher/antlr4-browser"; 2 | 3 | export class ErrorListener extends antlr4.error.ErrorListener { 4 | errors = []; 5 | 6 | // eslint-disable-next-line no-unused-vars 7 | syntaxError(rec, sym, line, col, msg, e) { 8 | const { start, stop } = sym || {}; 9 | if (msg === "mismatched input '' expecting {';', SP}") { 10 | // suppress error about missing semicolon at the end of a query 11 | return; 12 | } 13 | if (msg === "missing ';' at ''") { 14 | return; 15 | } 16 | if ( 17 | msg === 18 | "mismatched input '' expecting {':', CYPHER, EXPLAIN, PROFILE, USING, CREATE, DROP, LOAD, WITH, OPTIONAL, MATCH, UNWIND, MERGE, SET, DETACH, DELETE, REMOVE, FOREACH, RETURN, START, CALL}" 19 | ) { 20 | return; 21 | } 22 | this.errors.push({ line, col, msg, start, stop }); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /packages/editor-support/src/highlight/CypherSyntaxHighlight.js: -------------------------------------------------------------------------------- 1 | import { TreeUtils } from "../util/TreeUtils"; 2 | import * as CypherTypes from "../lang/CypherTypes"; 3 | 4 | function traverse(element, callback) { 5 | if (callback(element)) { 6 | // found, no need to go deeper 7 | return; 8 | } 9 | const c = element.getChildCount(); 10 | if (c === 0) { 11 | return; 12 | } 13 | for (let i = 0; i < c; i += 1) { 14 | traverse(element.getChild(i), callback); 15 | } 16 | } 17 | 18 | export class CypherSyntaxHighlight { 19 | static process(parseTree, callback) { 20 | traverse(parseTree, (e) => { 21 | const { start, stop } = TreeUtils.getPosition(e) || { start: 0, stop: 0 }; 22 | 23 | if (start > stop) { 24 | return false; 25 | } 26 | 27 | if (e instanceof CypherTypes.VARIABLE_CONTEXT) { 28 | callback(e, "variable"); 29 | return true; 30 | } 31 | 32 | if (e instanceof CypherTypes.NODE_LABEL_CONTEXT) { 33 | callback(e, "label"); 34 | return true; 35 | } 36 | 37 | if ( 38 | e instanceof CypherTypes.RELATIONSHIP_TYPE_CONTEXT || 39 | e instanceof CypherTypes.RELATIONSHIP_TYPE_OPTIONAL_COLON_CONTEXT 40 | ) { 41 | callback(e, "relationshipType"); 42 | return true; 43 | } 44 | 45 | if (e instanceof CypherTypes.PROPERTY_KEY_NAME_CONTEXT) { 46 | callback(e, "property"); 47 | return true; 48 | } 49 | 50 | if (e instanceof CypherTypes.PROCEDURE_NAME_CONTEXT) { 51 | callback(e, "procedure"); 52 | return true; 53 | } 54 | 55 | if (e instanceof CypherTypes.PROCEDURE_OUTPUT_CONTEXT) { 56 | callback(e, "procedureOutput"); 57 | return true; 58 | } 59 | 60 | if (e instanceof CypherTypes.FUNCTION_NAME_CONTEXT) { 61 | callback(e, "function"); 62 | return true; 63 | } 64 | 65 | if ( 66 | e instanceof CypherTypes.ALL_FUNCTION_NAME_CONTEXT || 67 | e instanceof CypherTypes.REDUCE_FUNCTION_NAME_CONTEXT || 68 | e instanceof CypherTypes.FILTER_FUNCTION_NAME_CONTEXT || 69 | e instanceof CypherTypes.NONE_FUNCTION_NAME_CONTEXT || 70 | e instanceof CypherTypes.EXTRACT_FUNCTION_NAME_CONTEXT || 71 | e instanceof CypherTypes.SHORTEST_PATH_FUNCTION_NAME_CONTEXT || 72 | e instanceof CypherTypes.ALL_SHORTEST_PATH_FUNCTION_NAME_CONTEXT || 73 | e instanceof CypherTypes.SINGLE_FUNCTION_NAME_CONTEXT || 74 | e instanceof CypherTypes.EXISTS_FUNCTION_NAME_CONTEXT || 75 | e instanceof CypherTypes.ANY_FUNCTION_NAME_CONTEXT 76 | ) { 77 | callback(e, "function"); 78 | return true; 79 | } 80 | 81 | if (e instanceof CypherTypes.PARAMETER_CONTEXT) { 82 | callback(e, "parameter"); 83 | return true; 84 | } 85 | 86 | if (e instanceof CypherTypes.CONSOLE_COMMAND_NAME_CONTEXT) { 87 | callback(e, "consoleCommand"); 88 | return true; 89 | } 90 | 91 | if ( 92 | e instanceof CypherTypes.CONSOLE_COMMAND_SUBCOMMAND_CONTEXT || 93 | e instanceof CypherTypes.CONSOLE_COMMAND_PATH_CONTEXT 94 | ) { 95 | callback(e, "property"); 96 | return true; 97 | } 98 | 99 | return false; 100 | }); 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /packages/editor-support/src/lang/CypherKeywords.js: -------------------------------------------------------------------------------- 1 | export default [ 2 | "CYPHER", 3 | "EXPLAIN", 4 | "PROFILE", 5 | "USING", 6 | "PERIODIC", 7 | "COMMIT", 8 | "UNION", 9 | "ALL", 10 | "CREATE", 11 | "DROP", 12 | "INDEX", 13 | "ON", 14 | "CONSTRAINT", 15 | "ASSERT", 16 | "IS", 17 | "UNIQUE", 18 | "EXISTS", 19 | "LOAD", 20 | "CSV", 21 | "WITH", 22 | "HEADERS", 23 | "FROM", 24 | "AS", 25 | "FIELDTERMINATOR", 26 | "OPTIONAL", 27 | "MATCH", 28 | "UNWIND", 29 | "MERGE", 30 | "SET", 31 | "DETACH", 32 | "DELETE", 33 | "REMOVE", 34 | "FOREACH", 35 | "IN", 36 | "DISTINCT", 37 | "RETURN", 38 | "ORDER", 39 | "BY", 40 | "SKIP", 41 | "LIMIT", 42 | "ASCENDING", 43 | "ASC", 44 | "DESCENDING", 45 | "DESC", 46 | "JOIN", 47 | "SCAN", 48 | "STARTS", 49 | "START", 50 | "NODE", 51 | "RELATIONSHIP", 52 | "REL", 53 | "WHERE", 54 | "SHORTESTPATH", 55 | "ALLSHORTESTPATHS", 56 | "OR", 57 | "XOR", 58 | "AND", 59 | "NOT", 60 | "ENDS", 61 | "CONTAINS", 62 | "NULL", 63 | "COUNT", 64 | "FILTER", 65 | "EXTRACT", 66 | "ANY", 67 | "NONE", 68 | "SINGLE", 69 | "TRUE", 70 | "FALSE", 71 | "REDUCE", 72 | "CASE", 73 | "ELSE", 74 | "END", 75 | "WHEN", 76 | "THEN", 77 | "CALL", 78 | "YIELD", 79 | "KEY", 80 | "CATALOG", 81 | "SHOW", 82 | "DEFAULT", 83 | "DBMS", 84 | "DATABASES", 85 | "DATABASE", 86 | "GRAPHS", 87 | "GRAPH", 88 | "REPLACE", 89 | "IF", 90 | "STOP", 91 | "ROLES", 92 | "ROLE", 93 | "USERS", 94 | "USER", 95 | "POPULATED", 96 | "PASSWORD", 97 | "CHANGE", 98 | "REQUIRED", 99 | "STATUS", 100 | "ACTIVE", 101 | "SUSPENDED", 102 | "ALTER", 103 | "CURRENT", 104 | "TO", 105 | "PRIVILEGES", 106 | "GRANT", 107 | "DENY", 108 | "REVOKE", 109 | "RELATIONSHIPS", 110 | "NODES", 111 | "ELEMENTS", 112 | "ELEMENT", 113 | "COPY", 114 | "OF", 115 | "TRAVERSE", 116 | "READ", 117 | "WRITE", 118 | "ACCESS", 119 | "INDEXES", 120 | "MANAGEMENT", 121 | "NEW", 122 | "LABELS", 123 | "LABEL", 124 | "NAMES", 125 | "NAME", 126 | "TYPES", 127 | "TYPE", 128 | "PROPERTY", 129 | "CONSTRAINTS", 130 | "ASSIGN", 131 | "BTREE", 132 | "EXIST", 133 | "FOR", 134 | "OPTIONS", 135 | "EXECUTE", 136 | "DEFINED", 137 | "FUNCTION", 138 | "FUNCTIONS", 139 | "BOOSTED", 140 | "PROCEDURE", 141 | "PROCEDURES", 142 | "ADMIN", 143 | "ADMINISTRATOR", 144 | "BRIEF", 145 | "VERBOSE", 146 | "OUTPUT" 147 | ]; 148 | -------------------------------------------------------------------------------- /packages/editor-support/src/lang/CypherTypes.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable max-len */ 2 | import { CypherParser } from "@neo4j-cypher/antlr4"; 3 | 4 | export const VARIABLE_CONTEXT = CypherParser.VariableContext; 5 | export const LABEL_NAME_CONTEXT = CypherParser.LabelNameContext; 6 | export const RELATIONSHIP_TYPE_NAME_CONTEXT = CypherParser.RelTypeNameContext; 7 | export const PROPERTY_KEY_NAME_CONTEXT = CypherParser.PropertyKeyNameContext; 8 | export const PARAMETER_NAME_CONTEXT = CypherParser.ParameterNameContext; 9 | export const PARAMETER_CONTEXT = CypherParser.ParameterContext; 10 | export const FUNCTION_NAME_CONTEXT = CypherParser.FunctionInvocationBodyContext; 11 | export const PROCEDURE_NAME_CONTEXT = 12 | CypherParser.ProcedureInvocationBodyContext; 13 | export const CONSOLE_COMMAND_NAME_CONTEXT = 14 | CypherParser.CypherConsoleCommandNameContext; 15 | export const CONSOLE_COMMAND_CONTEXT = CypherParser.CypherConsoleCommandContext; 16 | export const CONSOLE_COMMAND_PARAMETERS_CONTEXT = 17 | CypherParser.CypherConsoleCommandParametersContext; 18 | export const CONSOLE_COMMAND_PARAMETER_CONTEXT = 19 | CypherParser.CypherConsoleCommandParameterContext; 20 | export const CONSOLE_COMMAND_SUBCOMMAND_CONTEXT = 21 | CypherParser.SubCommandContext; 22 | export const CONSOLE_COMMAND_PATH_CONTEXT = CypherParser.CommandPathContext; 23 | export const PROCEDURE_OUTPUT_CONTEXT = CypherParser.ProcedureOutputContext; 24 | export const PROCEDURE_RESULTS_CONTEXT = CypherParser.ProcedureResultsContext; 25 | 26 | export const ALL_FUNCTION_NAME_CONTEXT = CypherParser.AllFunctionNameContext; 27 | export const ANY_FUNCTION_NAME_CONTEXT = CypherParser.AnyFunctionNameContext; 28 | export const SINGLE_FUNCTION_NAME_CONTEXT = 29 | CypherParser.SingleFunctionNameContext; 30 | export const NONE_FUNCTION_NAME_CONTEXT = CypherParser.NoneFunctionNameContext; 31 | export const EXTRACT_FUNCTION_NAME_CONTEXT = 32 | CypherParser.ExtractFunctionNameContext; 33 | export const REDUCE_FUNCTION_NAME_CONTEXT = 34 | CypherParser.ReduceFunctionNameContext; 35 | export const SHORTEST_PATH_FUNCTION_NAME_CONTEXT = 36 | CypherParser.ShortestPathFunctionNameContext; 37 | export const ALL_SHORTEST_PATH_FUNCTION_NAME_CONTEXT = 38 | CypherParser.AllShortestPathFunctionNameContext; 39 | export const FILTER_FUNCTION_NAME_CONTEXT = 40 | CypherParser.FilterFunctionNameContext; 41 | export const EXISTS_FUNCTION_NAME_CONTEXT = 42 | CypherParser.ExistsFunctionNameContext; 43 | 44 | export const CALL_CONTEXT = CypherParser.CallContext; 45 | export const EXPRESSION_CONTEXT = CypherParser.ExpressionContext; 46 | export const PATTERN_ELEMENT_CONTEXT = CypherParser.PatternElementContext; 47 | export const NODE_PATTERN_CONTEXT = CypherParser.NodePatternContext; 48 | export const NODE_LABEL_CONTEXT = CypherParser.NodeLabelContext; 49 | export const NODE_LABELS_CONTEXT = CypherParser.NodeLabelsContext; 50 | export const RELATIONSHIP_TYPE_CONTEXT = CypherParser.RelationshipTypeContext; 51 | export const RELATIONSHIP_TYPE_OPTIONAL_COLON_CONTEXT = 52 | CypherParser.RelationshipTypeOptionalColonContext; 53 | export const RELATIONSHIP_TYPES_CONTEXT = CypherParser.RelationshipTypesContext; 54 | export const RELATIONSHIP_PATTERN_CONTEXT = 55 | CypherParser.RelationshipPatternContext; 56 | export const PROPERTY_LOOKUP_CONTEXT = CypherParser.PropertyLookupContext; 57 | export const MAP_LITERAL_CONTEXT = CypherParser.MapLiteralContext; 58 | export const PROPERTIES_CONTEXT = CypherParser.PropertiesContext; 59 | export const MAP_LITERAL_ENTRY = CypherParser.LiteralEntryContext; 60 | export const STRING_LITERAL_CONTEXT = CypherParser.StringLiteralContext; 61 | export const ATOM_CONTEXT = CypherParser.AtomContext; 62 | 63 | export const QUERY_CONTEXT = CypherParser.CypherQueryContext; 64 | export const SYMBOLIC_NAME_CONTEXT = CypherParser.SymbolicNameContext; 65 | 66 | export const COMPLETION_CANDIDATES = [ 67 | STRING_LITERAL_CONTEXT, 68 | VARIABLE_CONTEXT, 69 | PROCEDURE_NAME_CONTEXT, 70 | FUNCTION_NAME_CONTEXT, 71 | CONSOLE_COMMAND_NAME_CONTEXT, 72 | NODE_LABEL_CONTEXT, 73 | RELATIONSHIP_TYPE_CONTEXT, 74 | RELATIONSHIP_TYPE_OPTIONAL_COLON_CONTEXT 75 | ]; 76 | 77 | export const SYMBOLIC_CONTEXTS = [ 78 | VARIABLE_CONTEXT, 79 | LABEL_NAME_CONTEXT, 80 | RELATIONSHIP_TYPE_NAME_CONTEXT, 81 | PROPERTY_KEY_NAME_CONTEXT, 82 | PARAMETER_NAME_CONTEXT 83 | ]; 84 | -------------------------------------------------------------------------------- /packages/editor-support/src/references/ReferencesListener.js: -------------------------------------------------------------------------------- 1 | import { CypherListener } from "@neo4j-cypher/antlr4"; 2 | import * as CypherTypes from "../lang/CypherTypes"; 3 | 4 | class Index { 5 | names = {}; 6 | namesByQuery = []; 7 | referencesByName = {}; 8 | referencesByQueryAndName = []; 9 | 10 | addQuery() { 11 | this.namesByQuery.push([]); 12 | this.referencesByQueryAndName.push({}); 13 | } 14 | 15 | add(ctx, addName = true) { 16 | const queryIndex = this.namesByQuery.length - 1; 17 | const text = ctx.getText(); 18 | if (addName) { 19 | this.names[text] = true; 20 | this.namesByQuery[queryIndex][text] = true; 21 | } 22 | this.referencesByName[text] = [...(this.referencesByName[text] || []), ctx]; 23 | const index = this.referencesByQueryAndName[queryIndex]; 24 | index[text] = [...(index[text] || []), ctx]; 25 | } 26 | 27 | /** 28 | * Variables have specific rules, because they participate in autocompletion. 29 | * We should not add to the names list variables that are in expression. 30 | */ 31 | addVariable(ctx) { 32 | let addName = true; 33 | 34 | // If variable is inside atom, then variable is inside expression. 35 | // Therefore, variables is node defined here. 36 | const parent = ctx.parentCtx; 37 | if (parent && parent instanceof CypherTypes.ATOM_CONTEXT) { 38 | addName = false; 39 | } 40 | this.add(ctx, addName); 41 | } 42 | } 43 | 44 | export class ReferencesListener extends CypherListener { 45 | queries = []; 46 | queriesAndCommands = []; 47 | statements = []; 48 | raw = []; 49 | 50 | indexes = new Map(); 51 | 52 | inConsoleCommand = false; 53 | 54 | constructor() { 55 | super(); 56 | CypherTypes.SYMBOLIC_CONTEXTS.forEach((sc) => { 57 | this.indexes.set(sc, new Index(sc)); 58 | }); 59 | } 60 | 61 | enterRaw(ctx) { 62 | this.raw.push(ctx); 63 | } 64 | exitRaw(ctx) { 65 | if (this.raw.length === 0) { 66 | this.raw.push(ctx); 67 | } 68 | } 69 | 70 | enterCypherPart(ctx) { 71 | this.statements.push(ctx); 72 | } 73 | 74 | exitCypher(ctx) { 75 | if (this.statements.length === 0) { 76 | this.statements.push(ctx); 77 | } 78 | } 79 | 80 | enterCypherConsoleCommand(ctx) { 81 | this.queriesAndCommands.push(ctx); 82 | this.indexes.forEach((index) => index.addQuery()); 83 | this.inConsoleCommand = true; 84 | } 85 | 86 | exitCypherConsoleCommand() { 87 | this.inConsoleCommand = false; 88 | } 89 | 90 | enterCypherQuery(ctx) { 91 | this.queries.push(ctx); 92 | this.queriesAndCommands.push(ctx); 93 | this.indexes.forEach((index) => index.addQuery()); 94 | } 95 | 96 | exitVariable(ctx) { 97 | if (this.inConsoleCommand) { 98 | return; 99 | } 100 | this.indexes.get(CypherTypes.VARIABLE_CONTEXT).addVariable(ctx); 101 | } 102 | 103 | exitLabelName(ctx) { 104 | if (this.inConsoleCommand) { 105 | return; 106 | } 107 | this.indexes.get(CypherTypes.LABEL_NAME_CONTEXT).add(ctx); 108 | } 109 | 110 | exitRelTypeName(ctx) { 111 | if (this.inConsoleCommand) { 112 | return; 113 | } 114 | this.indexes.get(CypherTypes.RELATIONSHIP_TYPE_NAME_CONTEXT).add(ctx); 115 | } 116 | 117 | exitPropertyKeyName(ctx) { 118 | if (this.inConsoleCommand) { 119 | return; 120 | } 121 | this.indexes.get(CypherTypes.PROPERTY_KEY_NAME_CONTEXT).add(ctx); 122 | } 123 | 124 | exitParameterName(ctx) { 125 | if (this.inConsoleCommand) { 126 | return; 127 | } 128 | this.indexes.get(CypherTypes.PARAMETER_NAME_CONTEXT).add(ctx); 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /packages/editor-support/src/references/ReferencesProvider.js: -------------------------------------------------------------------------------- 1 | export class ReferencesProvider { 2 | queries = []; 3 | index = {}; 4 | 5 | constructor(queries, index) { 6 | const { names, namesByQuery, referencesByName, referencesByQueryAndName } = 7 | index; 8 | this.queries = queries; 9 | this.index = { 10 | names: Object.keys(names), 11 | namesByQuery: namesByQuery.map((q) => Object.keys(q)), 12 | referencesByName, 13 | referencesByQueryAndName 14 | }; 15 | } 16 | 17 | getReferences(name, query = null) { 18 | if (query == null) { 19 | return this.index.referencesByName[name]; 20 | } 21 | const pos = this.queries.indexOf(query); 22 | return (this.index.referencesByQueryAndName[pos] || {})[name]; 23 | } 24 | 25 | getNames(query = null) { 26 | if (query == null) { 27 | return this.index.names; 28 | } 29 | const pos = this.queries.indexOf(query); 30 | return this.index.namesByQuery[pos] || []; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /packages/editor-support/src/util/PositionConverter.js: -------------------------------------------------------------------------------- 1 | export class PositionConverter { 2 | newLines = []; 3 | 4 | constructor(input) { 5 | for (let i = 0; i < input.length; i += 1) { 6 | if (input[i] === "\n") { 7 | this.newLines.push(i); 8 | } 9 | } 10 | } 11 | 12 | toAbsolute(line, column) { 13 | return (this.newLines[line - 2] || -1) + column + 1; 14 | } 15 | 16 | toRelative(abs) { 17 | for (let i = this.newLines.length - 1; i >= 0; i -= 1) { 18 | const column = abs - this.newLines[i]; 19 | if (column >= 1) { 20 | return { line: i + 2, column: column - 1 }; 21 | } 22 | } 23 | 24 | return { line: 1, column: abs }; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /packages/editor-support/src/util/TreeUtils.js: -------------------------------------------------------------------------------- 1 | export class TreeUtils { 2 | static findParent(pt, type) { 3 | let el = pt; 4 | while (true) { 5 | // eslint-disable-line no-constant-condition 6 | if (el == null) { 7 | return null; 8 | } 9 | if (el instanceof type) { 10 | return el; 11 | } 12 | el = el.parentCtx; 13 | } 14 | } 15 | 16 | static findAnyParent(pt, types = []) { 17 | let el = pt; 18 | while (true) { 19 | // eslint-disable-line no-constant-condition 20 | if (el == null) { 21 | return null; 22 | } 23 | for (let type of types) { 24 | if (el instanceof type) { 25 | return el; 26 | } 27 | } 28 | 29 | el = el.parentCtx; 30 | } 31 | } 32 | 33 | static findChild(element, type) { 34 | if (element == null) { 35 | return null; 36 | } 37 | 38 | if (element instanceof type) { 39 | return element; 40 | } 41 | 42 | if (element.children != null) { 43 | for (let i = 0; i < element.children.length; i += 1) { 44 | const e = element.children[i]; 45 | const result = TreeUtils.findChild(e, type); 46 | if (result != null) { 47 | return result; 48 | } 49 | } 50 | } 51 | 52 | return null; 53 | } 54 | 55 | static getPosition(el) { 56 | if (el != null) { 57 | const { start, stop, symbol } = el; 58 | if (symbol != null) { 59 | return { 60 | start: symbol.start, 61 | stop: symbol.stop 62 | }; 63 | } else if (start != null && stop != null) { 64 | return { 65 | start: start.start, 66 | stop: stop.stop 67 | }; 68 | } 69 | } 70 | 71 | return null; 72 | } 73 | 74 | static hasErrorNode(element) { 75 | if (element == null) { 76 | return false; 77 | } 78 | 79 | if (element.isErrorNode && element.isErrorNode()) { 80 | return true; 81 | } 82 | 83 | if (element.children != null) { 84 | for (let i = 0; i < element.children.length; i += 1) { 85 | const e = element.children[i]; 86 | const childHasErrorNode = TreeUtils.hasErrorNode(e); 87 | if (childHasErrorNode) { 88 | return true; 89 | } 90 | } 91 | } 92 | 93 | return false; 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /packages/editor-support/src/util/createCypherLexer.js: -------------------------------------------------------------------------------- 1 | import antrl4 from "@neo4j-cypher/antlr4-browser"; 2 | import { CypherLexer } from "@neo4j-cypher/antlr4"; 3 | 4 | export const createCypherLexer = (input) => { 5 | const chars = new antrl4.InputStream(input); 6 | return new CypherLexer(chars); 7 | }; 8 | -------------------------------------------------------------------------------- /packages/editor-support/src/util/ecsapeCypher.js: -------------------------------------------------------------------------------- 1 | export const ecsapeCypher = (str) => { 2 | const prefix = str.startsWith(":") ? ":" : ""; 3 | let content = str; 4 | if (prefix.length > 0) { 5 | content = str.substring(1); 6 | } 7 | return /^[A-Za-z][A-Za-z0-9_]*$/.test(content) 8 | ? prefix + content 9 | : `${prefix}\`${content.replace(/`/g, "``")}\``; 10 | }; 11 | -------------------------------------------------------------------------------- /packages/editor-support/src/util/parse.js: -------------------------------------------------------------------------------- 1 | import antlr4 from "@neo4j-cypher/antlr4-browser"; 2 | import { ReferencesProvider } from "../references/ReferencesProvider"; 3 | import * as CypherTypes from "../lang/CypherTypes"; 4 | import { CypherParser, CypherLexer } from "@neo4j-cypher/antlr4"; 5 | import { ErrorListener } from "../errors/ErrorListener"; 6 | import { ReferencesListener } from "../references/ReferencesListener"; 7 | 8 | export const parse = (input) => { 9 | const referencesListener = new ReferencesListener(); 10 | const errorListener = new ErrorListener(); 11 | const chars = new antlr4.InputStream(input); 12 | const lexer = new CypherLexer(chars); 13 | lexer.removeErrorListeners(); 14 | lexer.addErrorListener(errorListener); 15 | const tokens = new antlr4.CommonTokenStream(lexer); 16 | const parser = new CypherParser(tokens); 17 | parser.buildParseTrees = true; 18 | parser.removeErrorListeners(); 19 | parser.addErrorListener(errorListener); 20 | parser.addParseListener(referencesListener); 21 | const parseTree = parser.cypher(); 22 | const { queries, indexes } = referencesListener; 23 | 24 | const referencesProviders = new Map(); 25 | CypherTypes.SYMBOLIC_CONTEXTS.forEach((sc) => { 26 | referencesProviders.set( 27 | sc, 28 | new ReferencesProvider(queries, indexes.get(sc)) 29 | ); 30 | }); 31 | 32 | return { parseTree, referencesListener, errorListener, referencesProviders }; 33 | }; 34 | -------------------------------------------------------------------------------- /packages/editor-support/src/util/retryOperation.js: -------------------------------------------------------------------------------- 1 | const wait = (ms) => new Promise((r) => setTimeout(r, ms)); 2 | 3 | export const retryOperation = (operation, delay, times) => 4 | new Promise((resolve, reject) => 5 | operation() 6 | .then(resolve) 7 | .catch((reason) => { 8 | if (times - 1 > 0) { 9 | return wait(delay) 10 | .then(retryOperation.bind(null, operation, delay, times - 1)) 11 | .then(resolve) 12 | .catch(reject); 13 | } 14 | return reject(reason); 15 | }) 16 | ); 17 | -------------------------------------------------------------------------------- /packages/extract-statements/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @neo4j-cypher/extract-statements 2 | 3 | ## 1.0.2 4 | 5 | ### Patch Changes 6 | 7 | - Updated dependencies [bdae809] 8 | - @neo4j-cypher/editor-support@1.0.2 9 | 10 | ## 1.0.1 11 | 12 | ### Patch Changes 13 | 14 | - 54698be: Export util functions and types for usage in Neo4j Browser 15 | - Updated dependencies [54698be] 16 | - @neo4j-cypher/editor-support@1.0.1 17 | 18 | ## 1.0.0 19 | 20 | ### Major Changes 21 | 22 | - 13f7151: Initial pre-release 23 | 24 | ### Patch Changes 25 | 26 | - 896eddf: add missing @babel/runtime dependency 27 | - 8ba2deb: Exit pre-release mode 28 | - 8549a61: Apply workaround for node 18.14.0 support 29 | - 48363de: add antlr4-browser package (remove fs dependency) 30 | - acd35e1: Update repo url after move 31 | - 45a590b: Change license from GPL-3.0 to Apache-2.0 32 | - 91cb80a: Fix module exports + add shallow comparision on schema updates 33 | - Updated dependencies [6e6269f] 34 | - Updated dependencies [896eddf] 35 | - Updated dependencies [8ba2deb] 36 | - Updated dependencies [8549a61] 37 | - Updated dependencies [48363de] 38 | - Updated dependencies [acd35e1] 39 | - Updated dependencies [45a590b] 40 | - Updated dependencies [91cb80a] 41 | - Updated dependencies [13f7151] 42 | - @neo4j-cypher/editor-support@1.0.0 43 | - @neo4j-cypher/antlr4-simple@1.0.0 44 | 45 | ## 1.0.0-next.6 46 | 47 | ### Patch Changes 48 | 49 | - 8549a61: Apply workaround for node 18.14.0 support 50 | - Updated dependencies [8549a61] 51 | - @neo4j-cypher/antlr4-simple@1.0.0-next.5 52 | - @neo4j-cypher/editor-support@1.0.0-next.6 53 | 54 | ## 1.0.0-next.5 55 | 56 | ### Patch Changes 57 | 58 | - acd35e1: Update repo url after move 59 | - 45a590b: Change license from GPL-3.0 to Apache-2.0 60 | - Updated dependencies [acd35e1] 61 | - Updated dependencies [45a590b] 62 | - @neo4j-cypher/editor-support@1.0.0-next.5 63 | - @neo4j-cypher/antlr4-simple@1.0.0-next.4 64 | 65 | ## 1.0.0-next.4 66 | 67 | ### Patch Changes 68 | 69 | - 91cb80a: Fix module exports + add shallow comparision on schema updates 70 | - Updated dependencies [91cb80a] 71 | - @neo4j-cypher/antlr4-simple@1.0.0-next.3 72 | - @neo4j-cypher/editor-support@1.0.0-next.4 73 | 74 | ## 1.0.0-next.3 75 | 76 | ### Patch Changes 77 | 78 | - Updated dependencies [6e6269f] 79 | - @neo4j-cypher/editor-support@1.0.0-next.3 80 | 81 | ## 1.0.0-next.2 82 | 83 | ### Patch Changes 84 | 85 | - 48363de: add antlr4-browser package (remove fs dependency) 86 | - Updated dependencies [48363de] 87 | - @neo4j-cypher/antlr4-simple@1.0.0-next.2 88 | - @neo4j-cypher/editor-support@1.0.0-next.2 89 | 90 | ## 1.0.0-next.1 91 | 92 | ### Patch Changes 93 | 94 | - 896eddf: add missing @babel/runtime dependency 95 | - Updated dependencies [896eddf] 96 | - @neo4j-cypher/antlr4-simple@1.0.0-next.1 97 | - @neo4j-cypher/editor-support@1.0.0-next.1 98 | 99 | ## 1.0.0-next.0 100 | 101 | ### Major Changes 102 | 103 | - 13f7151: Initial pre-release 104 | 105 | ### Patch Changes 106 | 107 | - Updated dependencies [13f7151] 108 | - @neo4j-cypher/antlr4-simple@1.0.0-next.0 109 | - @neo4j-cypher/editor-support@1.0.0-next.0 110 | -------------------------------------------------------------------------------- /packages/extract-statements/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@neo4j-cypher/extract-statements", 3 | "description": "Utility function to extract statements from a cypher query", 4 | "keywords": [ 5 | "cypher", 6 | "extract", 7 | "statements" 8 | ], 9 | "version": "1.0.2", 10 | "author": "Neo4j Inc.", 11 | "license": "Apache-2.0", 12 | "main": "./lib/index.js", 13 | "module": "./es/index.js", 14 | "exports": { 15 | ".": { 16 | "import": "./es/index.js", 17 | "require": "./lib/index.js" 18 | }, 19 | "./src/index.js": { 20 | "import": "./src/index.js" 21 | } 22 | }, 23 | "types": "src/index.d.ts", 24 | "repository": { 25 | "type": "git", 26 | "url": "git://github.com/neo4j/cypher-editor.git" 27 | }, 28 | "bugs": { 29 | "url": "https://github.com/neo4j/cypher-editor/issues" 30 | }, 31 | "scripts": { 32 | "build-lib": "babel --config-file ../../babel.config.js --extensions \".js\" --out-dir lib ./src", 33 | "build-es": "cross-env ES=true babel --config-file ../../babel.config.js --extensions \".js\" --out-dir es ./src", 34 | "build": "npm run build-lib && npm run build-es", 35 | "clean:build": "rimraf lib && rimraf es" 36 | }, 37 | "files": [ 38 | "es/", 39 | "lib/", 40 | "README.md" 41 | ], 42 | "engineStrict": true, 43 | "engines": { 44 | "node": ">=14.0.0" 45 | }, 46 | "dependencies": { 47 | "@babel/runtime": "^7.20.13", 48 | "@neo4j-cypher/antlr4-simple": "1.0.0", 49 | "@neo4j-cypher/editor-support": "1.0.2" 50 | }, 51 | "devDependencies": { 52 | "@babel/cli": "^7.20.7", 53 | "@babel/core": "^7.20.12", 54 | "@babel/plugin-proposal-class-properties": "^7.18.6", 55 | "@babel/plugin-proposal-object-rest-spread": "^7.20.7", 56 | "@babel/plugin-transform-regenerator": "^7.20.5", 57 | "@babel/plugin-transform-runtime": "^7.19.6", 58 | "@babel/preset-env": "^7.20.2" 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /packages/extract-statements/src/ReferencesListener.simple.js: -------------------------------------------------------------------------------- 1 | import { CypherListener } from "@neo4j-cypher/antlr4-simple"; 2 | import { CypherTypes } from "@neo4j-cypher/editor-support"; 3 | 4 | class Index { 5 | names = {}; 6 | namesByQuery = []; 7 | referencesByName = {}; 8 | referencesByQueryAndName = []; 9 | 10 | addQuery() { 11 | this.namesByQuery.push([]); 12 | this.referencesByQueryAndName.push({}); 13 | } 14 | 15 | add(ctx, addName = true) { 16 | const queryIndex = this.namesByQuery.length - 1; 17 | const text = ctx.getText(); 18 | if (addName) { 19 | this.names[text] = true; 20 | this.namesByQuery[queryIndex][text] = true; 21 | } 22 | this.referencesByName[text] = [...(this.referencesByName[text] || []), ctx]; 23 | const index = this.referencesByQueryAndName[queryIndex]; 24 | index[text] = [...(index[text] || []), ctx]; 25 | } 26 | 27 | /** 28 | * Variables have specific rules, because they participate in autocompletion. 29 | * We should not add to the names list variables that are in expression. 30 | */ 31 | addVariable(ctx) { 32 | let addName = true; 33 | 34 | // If variable is inside atom, then variable is inside expression. 35 | // Therefore, variables is node defined here. 36 | const parent = ctx.parentCtx; 37 | if (parent && parent instanceof CypherTypes.ATOM_CONTEXT) { 38 | addName = false; 39 | } 40 | this.add(ctx, addName); 41 | } 42 | } 43 | 44 | export class ReferencesListener extends CypherListener { 45 | queries = []; 46 | queriesAndCommands = []; 47 | statements = []; 48 | raw = []; 49 | 50 | indexes = new Map(); 51 | 52 | inConsoleCommand = false; 53 | 54 | constructor() { 55 | super(); 56 | CypherTypes.SYMBOLIC_CONTEXTS.forEach((sc) => { 57 | this.indexes.set(sc, new Index(sc)); 58 | }); 59 | } 60 | 61 | enterRaw(ctx) { 62 | this.raw.push(ctx); 63 | } 64 | exitRaw(ctx) { 65 | if (this.raw.length === 0) { 66 | this.raw.push(ctx); 67 | } 68 | } 69 | 70 | enterCypherPart(ctx) { 71 | this.statements.push(ctx); 72 | } 73 | 74 | exitCypher(ctx) { 75 | if (this.statements.length === 0) { 76 | this.statements.push(ctx); 77 | } 78 | } 79 | 80 | enterCypherConsoleCommand(ctx) { 81 | this.queriesAndCommands.push(ctx); 82 | this.indexes.forEach((index) => index.addQuery()); 83 | this.inConsoleCommand = true; 84 | } 85 | 86 | exitCypherConsoleCommand() { 87 | this.inConsoleCommand = false; 88 | } 89 | 90 | enterCypherQuery(ctx) { 91 | this.queries.push(ctx); 92 | this.queriesAndCommands.push(ctx); 93 | this.indexes.forEach((index) => index.addQuery()); 94 | } 95 | 96 | exitVariable(ctx) { 97 | if (this.inConsoleCommand) { 98 | return; 99 | } 100 | this.indexes.get(CypherTypes.VARIABLE_CONTEXT).addVariable(ctx); 101 | } 102 | 103 | exitLabelName(ctx) { 104 | if (this.inConsoleCommand) { 105 | return; 106 | } 107 | this.indexes.get(CypherTypes.LABEL_NAME_CONTEXT).add(ctx); 108 | } 109 | 110 | exitRelTypeName(ctx) { 111 | if (this.inConsoleCommand) { 112 | return; 113 | } 114 | this.indexes.get(CypherTypes.RELATIONSHIP_TYPE_NAME_CONTEXT).add(ctx); 115 | } 116 | 117 | exitPropertyKeyName(ctx) { 118 | if (this.inConsoleCommand) { 119 | return; 120 | } 121 | this.indexes.get(CypherTypes.PROPERTY_KEY_NAME_CONTEXT).add(ctx); 122 | } 123 | 124 | exitParameterName(ctx) { 125 | if (this.inConsoleCommand) { 126 | return; 127 | } 128 | this.indexes.get(CypherTypes.PARAMETER_NAME_CONTEXT).add(ctx); 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /packages/extract-statements/src/extractStatements.js: -------------------------------------------------------------------------------- 1 | import antlr4 from "@neo4j-cypher/antlr4-browser"; 2 | import { 3 | ReferencesProvider, 4 | CypherTypes, 5 | ErrorListener 6 | } from "@neo4j-cypher/editor-support"; 7 | import { CypherParser, CypherLexer } from "@neo4j-cypher/antlr4-simple"; 8 | import { ReferencesListener } from "./ReferencesListener.simple"; 9 | 10 | export const extractStatements = (input) => { 11 | const referencesListener = new ReferencesListener(); 12 | const errorListener = new ErrorListener(); 13 | const chars = new antlr4.InputStream(input); 14 | const lexer = new CypherLexer(chars); 15 | lexer.removeErrorListeners(); 16 | lexer.addErrorListener(errorListener); 17 | const tokens = new antlr4.CommonTokenStream(lexer); 18 | const parser = new CypherParser(tokens); 19 | parser.buildParseTrees = true; 20 | parser.removeErrorListeners(); 21 | parser.addErrorListener(errorListener); 22 | parser.addParseListener(referencesListener); 23 | const parseTree = parser.cypher(); 24 | const { queries, indexes } = referencesListener; 25 | 26 | const referencesProviders = new Map(); 27 | CypherTypes.SYMBOLIC_CONTEXTS.forEach((sc) => { 28 | referencesProviders.set( 29 | sc, 30 | new ReferencesProvider(queries, indexes.get(sc)) 31 | ); 32 | }); 33 | return { parseTree, referencesListener, errorListener, referencesProviders }; 34 | }; 35 | -------------------------------------------------------------------------------- /packages/extract-statements/src/index.d.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Parses a cypher query and returns the statements. 3 | * 4 | * @param input the cypher query to parse 5 | */ 6 | declare function extractStatements(input: string): { 7 | referencesListener: { 8 | statements: [{ raw: () => Record[] }]; 9 | }; 10 | }; 11 | -------------------------------------------------------------------------------- /packages/extract-statements/src/index.js: -------------------------------------------------------------------------------- 1 | import { extractStatements } from "./extractStatements"; 2 | 3 | export { extractStatements }; 4 | -------------------------------------------------------------------------------- /packages/react-codemirror/README.md: -------------------------------------------------------------------------------- 1 | ### @neo4j-cypher/react-codemirror 2 | 3 | This package exports a React component that provides a cypher editor using codemirror 6. 4 | 5 | You can use this package like the following: 6 | 7 | ``` 8 | import React from 'react'; 9 | import CypherEditor from '@neo4j-cypher/react-codemirror'; 10 | 11 | const editorProps = { 12 | onValueChanged: value => {}, // optional 13 | onFocusChanged: focused => {}, // optional 14 | onScrollChanged: scrollInfo => {}, // optional 15 | onPositionChanged: ({ line, column, position }) => {}, // optional 16 | initialOptions: { 17 | theme: 'light', // optional, defaults to light 18 | extensions: [ /* override extensions */ ] // optional, defaults to a sensible list of extensions. 19 | }, 20 | initialSchema: { /* ... */ }, // optional, see example in demos 21 | initialValue: 'this is the text to show in the editor', 22 | initialPosition: { row: 2, column: 3}, // optional, rows are 1 based, columns are 0 based 23 | classNames: [], // optional, array of classnames to add to the root dom element. 24 | theme: 'light' // optional, should be light or dark, defaults to light 25 | }; 26 | 27 | const MyReactComponent = () => { 28 | return ( 29 | 30 | ); 31 | } 32 | ``` 33 | -------------------------------------------------------------------------------- /packages/react-codemirror/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@neo4j-cypher/react-codemirror", 3 | "description": "React CodeMirror 6 Cypher editor", 4 | "keywords": [ 5 | "react", 6 | "cypher", 7 | "codemirror", 8 | "codemirror 6" 9 | ], 10 | "version": "1.0.4", 11 | "author": "Neo4j Inc.", 12 | "license": "Apache-2.0", 13 | "main": "./lib/react-codemirror.js", 14 | "module": "./es/react-codemirror.js", 15 | "exports": { 16 | ".": { 17 | "import": "./es/react-codemirror.js", 18 | "require": "./lib/react-codemirror.js" 19 | }, 20 | "./src/react-codemirror.d.ts": { 21 | "import": "./src/react-codemirror.d.ts" 22 | }, 23 | "./src/react-codemirror.js": { 24 | "import": "./src/react-codemirror.js" 25 | } 26 | }, 27 | "types": "src/react-codemirror.d.ts", 28 | "repository": { 29 | "type": "git", 30 | "url": "git://github.com/neo4j/cypher-editor.git" 31 | }, 32 | "bugs": { 33 | "url": "https://github.com/neo4j/cypher-editor/issues" 34 | }, 35 | "scripts": { 36 | "build-lib": "babel --config-file ../../babel.react.config.js --extensions \".js\" --out-dir lib ./src", 37 | "build-es": "cross-env ES=true babel --config-file ../../babel.react.config.js --extensions \".js\" --out-dir es ./src", 38 | "build": "npm run build-lib && npm run build-es", 39 | "clean:build": "rimraf lib && rimraf es" 40 | }, 41 | "files": [ 42 | "src/*.d.ts", 43 | "es/", 44 | "lib/", 45 | "README.md" 46 | ], 47 | "engineStrict": true, 48 | "engines": { 49 | "node": ">=16" 50 | }, 51 | "dependencies": { 52 | "@babel/runtime": "^7.20.13", 53 | "@neo4j-cypher/codemirror": "1.0.3" 54 | }, 55 | "peerDependencies": { 56 | "react": ">=16" 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /packages/react-codemirror/src/react-codemirror.d.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This package provides a React Cypher Editor component 3 | * 4 | * @remarks 5 | * 6 | * The props for this component are defined by the {@link react-codemirror#CypherEditorProps | CypherEditorProps} interface 7 | * 8 | * @example 9 | * Here's some example code using the props: 10 | * 11 | * ```ts 12 | * const props = { autocomplete: false }; 13 | * 14 | * ``` 15 | * 16 | * @packageDocumentation 17 | */ 18 | export { default as CypherEditor, CypherEditorProps } from "./CypherEditor"; 19 | -------------------------------------------------------------------------------- /packages/react-codemirror/src/react-codemirror.js: -------------------------------------------------------------------------------- 1 | export { default as CypherEditor } from "./CypherEditor"; 2 | -------------------------------------------------------------------------------- /packages/svelte-codemirror/README.md: -------------------------------------------------------------------------------- 1 | ### @neo4j-cypher/svelte-codemirror 2 | 3 | This package exports a Svelte component that provides a cypher editor using codemirror 6. 4 | 5 | You can use this package like the following full app example: 6 | 7 | ``` 8 | 59 | 60 |
61 | 68 | {#if viewState !== "loading" && response} 69 |
70 | {#await response then res} 71 | {JSON.stringify(res.records, null, 2)} 72 | {:catch e} 73 | {e} 74 | {/await} 75 |
76 | {/if} 77 |
78 | 79 | 98 | 99 | ``` 100 | -------------------------------------------------------------------------------- /packages/svelte-codemirror/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@neo4j-cypher/svelte-codemirror", 3 | "description": "Svelte CodeMirror 6 Cypher editor", 4 | "keywords": [ 5 | "svelte", 6 | "cypher", 7 | "codemirror", 8 | "codemirror 6" 9 | ], 10 | "version": "1.0.5", 11 | "author": "Neo4j Inc.", 12 | "license": "Apache-2.0", 13 | "svelte": "src/svelte-codemirror.js", 14 | "types": "src/svelte-codemirror.d.ts", 15 | "repository": { 16 | "type": "git", 17 | "url": "git://github.com/neo4j/cypher-editor.git" 18 | }, 19 | "bugs": { 20 | "url": "https://github.com/neo4j/cypher-editor/issues" 21 | }, 22 | "files": [ 23 | "src/*.d.ts", 24 | "src/", 25 | "README.md" 26 | ], 27 | "engineStrict": true, 28 | "engines": { 29 | "node": ">=16" 30 | }, 31 | "dependencies": { 32 | "@neo4j-cypher/codemirror": "1.0.3" 33 | }, 34 | "peerDependencies": { 35 | "svelte": "^3.49.0" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /packages/svelte-codemirror/src/svelte-codemirror.d.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This package provides a Svelte Cypher Editor component 3 | * 4 | * @remarks 5 | * 6 | * The props for this component are defined by the {@link svelte-codemirror#CypherEditorProps | CypherEditorProps} interface 7 | * 8 | * @example 9 | * Here's some example code using the props: 10 | * 11 | * ```ts 12 | * const props = { autocomplete: false }; 13 | * 14 | * ``` 15 | * 16 | * @packageDocumentation 17 | */ 18 | 19 | export { 20 | default as CypherEditor, 21 | type CypherEditorProps 22 | } from "./CypherEditor.svelte"; 23 | -------------------------------------------------------------------------------- /packages/svelte-codemirror/src/svelte-codemirror.js: -------------------------------------------------------------------------------- 1 | export { default as CypherEditor } from "./CypherEditor.svelte"; 2 | -------------------------------------------------------------------------------- /playwright.config.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | import { devices } from "@playwright/test"; 3 | 4 | /** 5 | * See https://playwright.dev/docs/test-configuration. 6 | */ 7 | 8 | /** @type {import('@playwright/test').PlaywrightTestConfig} */ 9 | const config = { 10 | testDir: "./e2e-tests", 11 | outputDir: "playwright-results/e2e-results" + process.env.PORT, 12 | reporter: [ 13 | [ 14 | "html", 15 | { outputFolder: "playwright-results/e2e-report" + process.env.PORT } 16 | ] 17 | ], 18 | /* Maximum time one test can run for. */ 19 | timeout: 30 * 1000, 20 | expect: { 21 | /** 22 | * Maximum time expect() should wait for the condition to be met. 23 | * For example in `await expect(locator).toHaveText();` 24 | */ 25 | timeout: 5000 26 | }, 27 | /* Run tests in files in parallel */ 28 | fullyParallel: true, 29 | /* Fail the build on CI if you accidentally left test.only in the source code. */ 30 | forbidOnly: !!process.env.CI, 31 | /* Retry on CI only */ 32 | retries: process.env.CI ? 2 : 0, 33 | /* Opt out of parallel tests on CI. */ 34 | workers: process.env.CI ? 1 : undefined, 35 | /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ 36 | use: { 37 | /* Maximum time each action such as `click()` can take. Defaults to 0 (no limit). */ 38 | actionTimeout: 0, 39 | /* Base URL to use in actions like `await page.goto('/')`. */ 40 | // baseURL: 'http://localhost:3000', 41 | 42 | /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ 43 | trace: "on-first-retry" 44 | }, 45 | 46 | /* Configure projects for major browsers */ 47 | projects: [ 48 | { 49 | name: "chromium", 50 | use: { 51 | ...devices["Desktop Chrome"] 52 | } 53 | }, 54 | 55 | { 56 | name: "firefox", 57 | use: { 58 | ...devices["Desktop Firefox"] 59 | } 60 | }, 61 | 62 | { 63 | name: "webkit", 64 | use: { 65 | ...devices["Desktop Safari"] 66 | } 67 | } 68 | ] 69 | }; 70 | 71 | export default config; 72 | -------------------------------------------------------------------------------- /turbo.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://turborepo.org/schema.json", 3 | "pipeline": { 4 | "start": { 5 | "cache": false 6 | }, 7 | "build": { 8 | "dependsOn": ["^build"], 9 | "outputs": ["lib/**", "es/**"] 10 | }, 11 | "deploy": { 12 | "dependsOn": ["build"], 13 | "outputs": ["dist/**"] 14 | }, 15 | "serve": { 16 | "dependsOn": ["deploy"], 17 | "cache": false 18 | }, 19 | "e2e": { 20 | "dependsOn": ["serve"], 21 | "cache": false 22 | }, 23 | "unserve": { 24 | "cache": false 25 | }, 26 | "clean:deploy": { 27 | "cache": false 28 | }, 29 | "clean:build": { 30 | "cache": false 31 | } 32 | } 33 | } 34 | --------------------------------------------------------------------------------