├── .changeset ├── README.md └── config.json ├── .circleci └── config.yml ├── .eslintrc.js ├── .git-blame-ignore-revs ├── .gitattributes ├── .github └── workflows │ ├── E2E.yml │ ├── build-prs.yml │ └── release.yml ├── .gitignore ├── .gitleaks.toml ├── .npmrc ├── .nvmrc ├── .prettierignore ├── .prettierrc ├── .semgrepignore ├── .vscode ├── extensions.json ├── launch.json ├── settings.json └── tasks.json ├── .vscodeignore ├── CHANGELOG.md ├── CODEOWNERS ├── LICENSE ├── README.md ├── apollo.connectors.mapping.configuration.json ├── codegen.yml ├── graphql.configuration.json ├── images ├── IconRun.svg ├── apollo.svg ├── engine-stats.png ├── icon-apollo-blue-400x400.png ├── marketplace │ ├── apollo-wordmark.png │ ├── autocomplete.gif │ ├── federation-directive-hover.png │ ├── jump-to-def.gif │ ├── perf-annotation.png │ ├── stats.gif │ ├── type-info.png │ └── warnings-and-errors.gif ├── query-with-vars.gif └── variable-argument-completion.gif ├── jest.config.ts ├── jest.e2e.config.js ├── package-lock.json ├── package.json ├── renovate.json ├── sampleWorkspace ├── clientSchema │ ├── apollo.config.cjs │ ├── src │ │ ├── clientSchema.js │ │ └── test.js │ └── starwarsSchema.graphql ├── configFileTypes │ ├── cjsConfig │ │ ├── apollo.config.cjs │ │ ├── package.json │ │ ├── src │ │ │ └── test.js │ │ └── starwarsSchema.graphql │ ├── jsConfigWithCJS │ │ ├── apollo.config.js │ │ ├── package.json │ │ ├── src │ │ │ └── test.js │ │ └── starwarsSchema.graphql │ ├── jsConfigWithESM │ │ ├── apollo.config.js │ │ ├── package.json │ │ ├── src │ │ │ └── test.js │ │ └── starwarsSchema.graphql │ ├── mjsConfig │ │ ├── apollo.config.mjs │ │ ├── package.json │ │ ├── src │ │ │ └── test.js │ │ └── starwarsSchema.graphql │ ├── tsConfigWithCJS │ │ ├── apollo.config.ts │ │ ├── package.json │ │ ├── src │ │ │ └── test.js │ │ └── starwarsSchema.graphql │ └── tsConfigWithESM │ │ ├── apollo.config.ts │ │ ├── package.json │ │ ├── src │ │ └── test.js │ │ └── starwarsSchema.graphql ├── connectors-community │ ├── .github │ │ ├── ISSUE_TEMPLATE │ │ │ ├── connector-bug-report.md │ │ │ └── new-connector.md │ │ └── renovate.json5 │ ├── .gitignore │ ├── .vscode │ │ ├── extensions.json │ │ ├── settings.json │ │ └── tasks.json │ ├── README.md │ ├── apollo.config.json │ ├── connectors │ │ ├── .template │ │ │ ├── Dockerfile │ │ │ ├── README │ │ │ ├── connector.graphql │ │ │ ├── router.yaml │ │ │ └── supergraph.yaml │ │ ├── JSONPlaceholder │ │ │ ├── README │ │ │ ├── albums.graphql │ │ │ ├── comments.graphql │ │ │ ├── photos.graphql │ │ │ ├── posts.graphql │ │ │ ├── supergraph.yaml │ │ │ ├── todos.graphql │ │ │ └── users.graphql │ │ ├── TM-Forum │ │ │ ├── README.md │ │ │ ├── router.yaml │ │ │ ├── supergraph.yaml │ │ │ └── tmf622-ProductOrdering.graphql │ │ ├── adobe-commerce-cloud │ │ │ ├── README.md │ │ │ ├── addresses.graphql │ │ │ ├── customer.graphql │ │ │ ├── products.graphql │ │ │ ├── router.yaml │ │ │ ├── supergraph.yaml │ │ │ └── swagger.json │ │ ├── anthropic │ │ │ ├── Dockerfile │ │ │ ├── README │ │ │ ├── messages.graphql │ │ │ ├── router.yaml │ │ │ └── supergraph.yaml │ │ ├── apollo-ecomm-simple │ │ │ ├── README │ │ │ ├── connector.graphql │ │ │ ├── router.yaml │ │ │ └── supergraph.yaml │ │ ├── apple │ │ │ ├── README │ │ │ ├── app-store-connect.graphql │ │ │ ├── router.yaml │ │ │ └── supergraph.yaml │ │ ├── aws │ │ │ ├── README │ │ │ ├── dynamodb.graphql │ │ │ ├── json-responses │ │ │ │ ├── product-price.json │ │ │ │ └── products.json │ │ │ ├── lambda.graphql │ │ │ ├── router.yaml │ │ │ └── supergraph.yaml │ │ ├── bored │ │ │ ├── README.md │ │ │ ├── bored.graphql │ │ │ └── supergraph.yaml │ │ ├── common-room │ │ │ ├── README.md │ │ │ ├── contacts.graphql │ │ │ ├── json-responses │ │ │ │ └── members_email_.json │ │ │ ├── router.yaml │ │ │ └── supergraph.yaml │ │ ├── googlemaps │ │ │ ├── README.md │ │ │ ├── distancematrix.graphql │ │ │ ├── places-legacy.graphql │ │ │ ├── places.graphql │ │ │ ├── router.yaml │ │ │ ├── supergraph.yaml │ │ │ └── timezone.graphql │ │ ├── heygen │ │ │ ├── README │ │ │ ├── avatars.graphql │ │ │ ├── photo-avatars.graphql │ │ │ ├── router.yaml │ │ │ └── supergraph.yaml │ │ ├── jira │ │ │ ├── README │ │ │ ├── connector.graphql │ │ │ ├── router.yaml │ │ │ └── supergraph.yaml │ │ ├── museums │ │ │ ├── README.md │ │ │ ├── chicagoArt.graphql │ │ │ ├── met.graphql │ │ │ └── supergraph.yaml │ │ ├── nws │ │ │ ├── README.md │ │ │ ├── alerts.graphql │ │ │ └── supergraph.yaml │ │ ├── odata │ │ │ ├── README │ │ │ ├── connector.graphql │ │ │ ├── router.yaml │ │ │ └── supergraph.yaml │ │ ├── openai │ │ │ ├── README.md │ │ │ ├── assistants.graphql │ │ │ ├── chat-completions.graphql │ │ │ ├── models.graphql │ │ │ ├── router.yaml │ │ │ └── supergraph.yaml │ │ ├── pokeapi │ │ │ ├── README │ │ │ ├── games.graphql │ │ │ ├── locations.graphql │ │ │ ├── moves.graphql │ │ │ ├── pokemon.graphql │ │ │ ├── router.yaml │ │ │ └── supergraph.yaml │ │ ├── strapi │ │ │ ├── README.md │ │ │ ├── router.yaml │ │ │ ├── supergraph.yaml │ │ │ └── users.graphql │ │ ├── stripe │ │ │ ├── README.md │ │ │ ├── checkout.graphql │ │ │ ├── core-resources.graphql │ │ │ ├── payment-methods.graphql │ │ │ ├── products.graphql │ │ │ ├── router.yaml │ │ │ └── supergraph.yaml │ │ ├── supabase │ │ │ ├── README.md │ │ │ ├── router.yaml │ │ │ ├── supabase.graphql │ │ │ └── supergraph.yaml │ │ ├── thespacedevs │ │ │ ├── README │ │ │ ├── agencies.graphql │ │ │ ├── api-throttle.graphql │ │ │ ├── astronauts.graphql │ │ │ ├── celestial-bodies.graphql │ │ │ ├── docking-events.graphql │ │ │ ├── launches.graphql │ │ │ └── supergraph.yaml │ │ ├── tint │ │ │ ├── README │ │ │ ├── accounts.graphql │ │ │ ├── router.yaml │ │ │ ├── social-feeds.graphql │ │ │ └── supergraph.yaml │ │ ├── todoist │ │ │ ├── README.md │ │ │ ├── supergraph.yaml │ │ │ └── todoist.graphql │ │ ├── trimblemaps │ │ │ ├── README │ │ │ ├── connector.graphql │ │ │ ├── router.yaml │ │ │ └── supergraph.yaml │ │ ├── twilio │ │ │ ├── README.md │ │ │ ├── messages.graphql │ │ │ ├── router.yaml │ │ │ └── supergraph.yaml │ │ ├── usgs │ │ │ ├── earthquakes-nominatum │ │ │ │ ├── README.md │ │ │ │ ├── earthquake-simple.graphql │ │ │ │ ├── router.yaml │ │ │ │ └── supergraph.yaml │ │ │ └── earthquakes │ │ │ │ ├── README.md │ │ │ │ ├── earthquakes.graphql │ │ │ │ └── supergraph.yaml │ │ ├── usps │ │ │ ├── README │ │ │ ├── router.yaml │ │ │ ├── supergraph.yaml │ │ │ └── tracking.graphql │ │ └── zendesk │ │ │ ├── README │ │ │ ├── connector.graphql │ │ │ ├── router.yaml │ │ │ └── supergraph.yaml │ ├── file-new │ │ └── index.js │ ├── package-lock.json │ ├── package.json │ └── supergraph.yaml ├── fixtures │ └── starwarsSchema.graphql ├── httpSchema │ ├── apollo.config.ts │ ├── self-signed.crt │ ├── self-signed.key │ └── src │ │ └── test.js ├── localSchema │ ├── apollo.config.ts │ ├── src │ │ └── test.js │ └── starwarsSchema.graphql ├── localSchemaArray │ ├── apollo.config.json │ ├── planets.graphql │ ├── src │ │ └── test.js │ └── starwarsSchema.graphql ├── rover │ ├── apollo.config.yaml │ ├── src │ │ ├── test.graphql │ │ └── test.js │ └── supergraph.yaml ├── sampleWorkspace.code-workspace └── spotifyGraph │ ├── apollo.config.mjs │ └── src │ └── test.js ├── schemas ├── apollo.config.schema.json └── supergraph_config_schema.json ├── src ├── __e2e__ │ ├── mockServer.js │ ├── mocks.js │ ├── run.js │ ├── runTests.js │ ├── setup.js │ ├── vscode-environment.js │ └── vscode.js ├── __mocks__ │ └── fs.js ├── __tests__ │ ├── fixtures │ │ └── textmate │ │ │ ├── test.apollo.connectors.mapping │ │ │ └── test.connect.graphql │ └── statusBar.test.ts ├── build.js ├── debug.ts ├── devtools │ ├── DevToolsViewProvider.ts │ └── server.ts ├── env │ ├── index.ts │ └── typescript-utility-types.ts ├── extension.ts ├── language-server │ ├── __e2e__ │ │ ├── clientSchema.e2e.ts │ │ ├── configFileTypes.e2e.ts │ │ ├── httpSchema.e2e.ts │ │ ├── localSchema.e2e.ts │ │ ├── localSchemaArray.e2e.ts │ │ ├── rover.e2e.ts │ │ ├── studioGraph.e2e.ts │ │ └── utils.ts │ ├── __tests__ │ │ ├── diagnostics.test.ts │ │ ├── document.test.ts │ │ ├── fileSet.test.ts │ │ └── fixtures │ │ │ ├── TypeScript.tmLanguage.json │ │ │ ├── documents │ │ │ ├── commentWithTemplate.ts │ │ │ ├── commentWithTemplate.ts.snap │ │ │ ├── functionCall.ts │ │ │ ├── functionCall.ts.snap │ │ │ ├── taggedTemplate.ts │ │ │ ├── taggedTemplate.ts.snap │ │ │ ├── templateWithComment.ts │ │ │ └── templateWithComment.ts.snap │ │ │ └── starwarsSchema.ts │ ├── config │ │ ├── __tests__ │ │ │ ├── config.ts │ │ │ ├── loadConfig.ts │ │ │ └── utils.ts │ │ ├── cache-busting-resolver.js │ │ ├── cache-busting-resolver.types.ts │ │ ├── config.ts │ │ ├── index.ts │ │ ├── loadConfig.ts │ │ ├── loadTsConfig.ts │ │ ├── utils.ts │ │ └── which.d.ts │ ├── diagnostics.ts │ ├── document.ts │ ├── engine │ │ ├── index.ts │ │ └── operations │ │ │ ├── frontendUrlRoot.ts │ │ │ └── schemaTagsAndFieldStats.ts │ ├── errors │ │ ├── __tests__ │ │ │ └── NoMissingClientDirectives.test.ts │ │ ├── logger.ts │ │ └── validation.ts │ ├── fileSet.ts │ ├── format.ts │ ├── graphqlTypes.ts │ ├── index.ts │ ├── loadingHandler.ts │ ├── project │ │ ├── base.ts │ │ ├── client.ts │ │ ├── defaultClientSchema.ts │ │ ├── internal.ts │ │ └── rover │ │ │ ├── DocumentSynchronization.ts │ │ │ ├── __tests__ │ │ │ └── DocumentSynchronization.test.ts │ │ │ └── project.ts │ ├── providers │ │ └── schema │ │ │ ├── __tests__ │ │ │ └── file.ts │ │ │ ├── base.ts │ │ │ ├── endpoint.ts │ │ │ ├── engine.ts │ │ │ ├── file.ts │ │ │ └── index.ts │ ├── server.ts │ ├── typings │ │ └── graphql.d.ts │ ├── utilities │ │ ├── __tests__ │ │ │ ├── graphql.test.ts │ │ │ ├── source.test.ts │ │ │ └── uri.ts │ │ ├── debouncer.ts │ │ ├── debug.ts │ │ ├── graphql.ts │ │ ├── index.ts │ │ ├── languageIdForExtension.ts │ │ ├── source.ts │ │ └── uri.ts │ └── workspace.ts ├── languageServerClient.ts ├── messages.ts ├── statusBar.ts ├── tools │ ├── __tests__ │ │ ├── buildServiceDefinition.test.ts │ │ └── snapshotSerializers │ │ │ ├── astSerializer.ts │ │ │ └── graphQLTypeSerializer.ts │ ├── buildServiceDefinition.ts │ ├── index.ts │ ├── schema │ │ ├── index.ts │ │ ├── resolveObject.ts │ │ └── resolverMap.ts │ └── utilities │ │ ├── getLanguageInformation.ts │ │ ├── graphql.ts │ │ ├── index.ts │ │ ├── invariant.ts │ │ ├── languageInformation.ts │ │ └── predicates.ts └── utils.ts ├── start-ac.mjs ├── syntaxes ├── build.ts ├── connectors.mapping.json ├── connectors.mapping.yaml ├── graphql.connectors.json ├── graphql.connectors.yaml ├── graphql.dart.json ├── graphql.ex.json ├── graphql.js.json ├── graphql.json ├── graphql.lua.json ├── graphql.py.json ├── graphql.rb.json ├── graphql.re.json ├── publish.sh └── tsconfig.json ├── tsconfig.build.json └── tsconfig.json /.changeset/README.md: -------------------------------------------------------------------------------- 1 | # Changesets 2 | 3 | Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works 4 | with multi-package repos, or single-package repos to help you version and publish your code. You can 5 | find the full documentation for it [in our repository](https://github.com/changesets/changesets) 6 | 7 | We have a quick list of common questions to get you started engaging with this project in 8 | [our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md) 9 | -------------------------------------------------------------------------------- /.changeset/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://unpkg.com/@changesets/config@2.3.1/schema.json", 3 | "changelog": [ 4 | "@changesets/changelog-github", 5 | { "repo": "apollographql/vscode-graphql" } 6 | ], 7 | "commit": false, 8 | "fixed": [], 9 | "linked": [], 10 | "access": "public", 11 | "baseBranch": "main", 12 | "updateInternalDependencies": "patch", 13 | "ignore": [] 14 | } 15 | -------------------------------------------------------------------------------- /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 2.1 2 | 3 | orbs: 4 | secops: apollo/circleci-secops-orb@2.0.7 5 | 6 | executors: 7 | node: 8 | docker: 9 | - image: cimg/node:22.12.0 10 | working_directory: ~/vscode-graphql 11 | node24: 12 | docker: 13 | - image: cimg/node:24.4.0 14 | working_directory: ~/vscode-graphql 15 | 16 | commands: 17 | npm-install: 18 | steps: 19 | - restore_cache: 20 | name: Restore npm cache 21 | keys: 22 | - npm-packages-{{ checksum "package-lock.json" }}--{{ checksum ".circleci/config.yml" }} 23 | - run: 24 | name: Install dependencies 25 | command: npm ci --prefer-offline 26 | - save_cache: 27 | name: Save npm cache 28 | key: npm-packages-{{ checksum "package-lock.json" }}--{{ checksum ".circleci/config.yml" }} 29 | paths: 30 | - ~/.npm 31 | 32 | jobs: 33 | lint: 34 | executor: node 35 | steps: 36 | - checkout 37 | - npm-install 38 | - run: 39 | name: Run lint (currenty prettier) 40 | command: npm run lint 41 | 42 | typescript: 43 | executor: node 44 | steps: 45 | - checkout 46 | - npm-install 47 | - run: 48 | name: TypeScript Check 49 | command: npm run typecheck 50 | 51 | test: 52 | executor: node 53 | steps: 54 | - checkout 55 | - npm-install 56 | - run: 57 | name: Test 58 | command: npm run test -- --runInBand 59 | 60 | textmate: 61 | executor: node24 62 | steps: 63 | - checkout 64 | - npm-install 65 | - run: 66 | name: Build TextMate Grammar 67 | command: npm run build:textmate 68 | - run: 69 | name: Test TextMate Grammar 70 | command: npm run test:textmate 71 | 72 | workflows: 73 | build-test-deploy: 74 | jobs: 75 | - lint 76 | - typescript 77 | - test 78 | - textmate 79 | security-scans: 80 | jobs: 81 | - secops/gitleaks: 82 | context: 83 | - platform-docker-ro 84 | - github-orb 85 | - secops-oidc 86 | git-base-revision: <<#pipeline.git.base_revision>><><> 87 | git-revision: << pipeline.git.revision >> 88 | - secops/semgrep: 89 | context: 90 | - secops-oidc 91 | - github-orb 92 | git-base-revision: <<#pipeline.git.base_revision>><><> 93 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | parser: "@typescript-eslint/parser", 3 | plugins: ["prettier", "@typescript-eslint"], 4 | // Skip generated file. 5 | ignorePatterns: ["src/language-server/graphqlTypes.ts"], 6 | rules: { 7 | "prettier/prettier": "error", 8 | }, 9 | extends: ["prettier"], 10 | }; 11 | -------------------------------------------------------------------------------- /.git-blame-ignore-revs: -------------------------------------------------------------------------------- 1 | # Run format on codebase after upgrading Prettier 2 | d47effa7e7ad3494349d0ed5957501d1372ce59e 3 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | package-lock.json -diff 2 | -------------------------------------------------------------------------------- /.github/workflows/build-prs.yml: -------------------------------------------------------------------------------- 1 | name: Bundle Extension as Artifact Download 2 | on: 3 | pull_request: 4 | jobs: 5 | test: 6 | name: Bundle Extension as Artifact Download 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/checkout@v4 10 | - uses: actions/setup-node@v4 11 | with: 12 | cache: "npm" 13 | node-version: 24 14 | - run: npm ci 15 | - run: echo PKG_VERSION="$(git show --no-patch --format=0.0.0-build-%ct.pr-${{ github.event.pull_request.number }}.commit-%h)" >> $GITHUB_ENV 16 | - run: npm pkg set "version=${{ env.PKG_VERSION }}" 17 | - run: npx -y @vscode/vsce package --out vscode-apollo-${{ env.PKG_VERSION }}.vsix 18 | 19 | - uses: actions/upload-artifact@v4 20 | id: artifact-upload-step 21 | with: 22 | name: vscode-apollo-${{ env.PKG_VERSION }} 23 | path: vscode-apollo-${{ env.PKG_VERSION }}.vsix 24 | retention-days: 14 25 | 26 | - name: Output artifact URL 27 | run: echo 'Artifact URL is ${{ steps.artifact-upload-step.outputs.artifact-url }}' 28 | 29 | - name: Find Comment 30 | uses: peter-evans/find-comment@v3 31 | id: fc 32 | with: 33 | issue-number: ${{ github.event.pull_request.number }} 34 | comment-author: "github-actions[bot]" 35 | body-includes: 36 | 37 | - name: Create comment 38 | uses: peter-evans/create-or-update-comment@v4 39 | with: 40 | issue-number: ${{ github.event.pull_request.number }} 41 | comment-id: ${{ steps.fc.outputs.comment-id }} 42 | edit-mode: replace 43 | body: | 44 | 45 | You can download the latest build of the extension for this PR here: 46 | [vscode-apollo-${{ env.PKG_VERSION }}.zip](${{ steps.artifact-upload-step.outputs.artifact-url }}). 47 | 48 | To install the extension, download the file, unzip it and install it in VS Code by selecting "Install from VSIX..." in the Extensions view. 49 | 50 | Alternatively, run 51 | ```sh 52 | code --install-extension vscode-apollo-${{ env.PKG_VERSION }}.vsix --force 53 | ``` 54 | from the command line. 55 | 56 | For older builds, please see the edit history of this comment. 57 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | lib 3 | 4 | # TypeScript incremental compilation cache 5 | *.tsbuildinfo 6 | 7 | # Visual Studio Code workspace settings 8 | .vscode/* 9 | !.vscode/settings.json 10 | !.vscode/tasks.json 11 | !.vscode/launch.json 12 | !.vscode/extensions.json 13 | 14 | .DS_Store 15 | vscode-apollo-*.vsix 16 | .env 17 | 18 | # files generated from tests 19 | __tmp__* 20 | .vscode-test 21 | .yalc 22 | yalc.lock 23 | -------------------------------------------------------------------------------- /.gitleaks.toml: -------------------------------------------------------------------------------- 1 | # This file exists primarily to influence scheduled scans that Apollo runs of all repos in Apollo-managed orgs. 2 | # This is an Apollo-Internal link, but more information about these scans is available here: 3 | # https://apollographql.atlassian.net/wiki/spaces/SecOps/pages/81330213/Everything+Static+Application+Security+Testing#Scheduled-Scans.1 4 | # 5 | # Apollo is using Gitleaks (https://github.com/gitleaks/gitleaks) to run these scans. 6 | # However, this file is not something that Gitleaks natively consumes. This file is an 7 | # Apollo-convention. Prior to scanning a repo, Apollo merges 8 | # our standard Gitleaks configuration (which is largely just the Gitleaks-default config) with 9 | # this file if it exists in a repo. The combined config is then used to scan a repo. 10 | # 11 | # We did this because the natively-supported allowlisting functionality in Gitleaks didn't do everything we wanted 12 | # or wasn't as robust as we needed. For example, one of the allowlisting options offered by Gitleaks depends on the line number 13 | # on which a false positive secret exists to allowlist it. (https://github.com/gitleaks/gitleaks#gitleaksignore). 14 | # This creates a fairly fragile allowlisting mechanism. This file allows us to leverage the full capabilities of the Gitleaks rule syntax 15 | # to create allowlisting functionality. 16 | 17 | 18 | [[ rules ]] 19 | id = "generic-api-key" 20 | [ rules.allowlist ] 21 | commits = [ 22 | # This creates an allowlist for a UUID that was 23 | # used as an identifier, but is not secret 24 | # See https://github.com/apollographql/vscode-graphql/blob/a905280c143991b3fd675f8b4c3a7da277ccf095/packages/apollo-language-server/src/engine/index.ts#L86 25 | "a905280c143991b3fd675f8b4c3a7da277ccf095" 26 | ] 27 | 28 | [[ rules ]] 29 | id = "private-key" 30 | [ rules.allowlist ] 31 | paths = [ 32 | '''sampleWorkspace/httpSchema/self-signed.key$''', 33 | ] 34 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | provenance=true 2 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | 22 2 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | src/language-server/graphqlTypes.ts 2 | src/language-server/__tests__/fixtures/documents/commentWithTemplate.ts 3 | schemas/*.json 4 | syntaxes/*.json 5 | src/__tests__/fixtures/textmate/* 6 | README.md 7 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "tabWidth": 2, 3 | "useTabs": false, 4 | "singleQuote": false 5 | } 6 | -------------------------------------------------------------------------------- /.semgrepignore: -------------------------------------------------------------------------------- 1 | sampleWorkspace/connectors-community/** 2 | syntaxes/build.ts 3 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "redcmd.tmlanguage-syntax-highlighter" 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | // List of configurations. Add new configurations or edit existing ones. 4 | "configurations": [ 5 | { 6 | "name": "Launch VS Code Extension", 7 | "type": "extensionHost", 8 | "request": "launch", 9 | "preLaunchTask": "BuildAndStartWorkspace", 10 | "runtimeExecutable": "${execPath}", 11 | "args": [ 12 | "--extensionDevelopmentPath=${workspaceRoot}", 13 | "--disable-extensions", 14 | "${workspaceFolder}/sampleWorkspace/sampleWorkspace.code-workspace" 15 | ], 16 | "sourceMaps": true, 17 | "env": { 18 | "APOLLO_ENGINE_ENDPOINT": "http://localhost:7096/apollo", 19 | "APOLLO_FEATURE_FLAGS": "rover" 20 | //"APOLLO_ROVER_LANGUAGE_IDS": "graphql,javascript" 21 | }, 22 | "outFiles": ["${workspaceRoot}/lib/**/*.js"] 23 | }, 24 | { 25 | "name": "Attach to TS Server", 26 | "type": "node", 27 | "request": "attach", 28 | "protocol": "inspector", 29 | "port": 6009, 30 | "sourceMaps": true 31 | }, 32 | { 33 | "name": "Extension Tests", 34 | "type": "extensionHost", 35 | "request": "launch", 36 | "runtimeExecutable": "${execPath}", 37 | "args": [ 38 | "--disable-extensions", 39 | "--extensionDevelopmentPath=${workspaceFolder}", 40 | "--extensionTestsPath=${workspaceFolder}/src/__e2e__/run.js", 41 | "${workspaceFolder}/sampleWorkspace/sampleWorkspace.code-workspace" 42 | ], 43 | "outFiles": ["${workspaceFolder}/lib/**/*.js"], 44 | "preLaunchTask": "BuildAndStartWorkspace", 45 | "env": { "APOLLO_ENGINE_ENDPOINT": "http://localhost:7096/apollo" } 46 | }, 47 | { 48 | "name": "Attach to Test Debugger", 49 | "type": "node", 50 | "request": "attach", 51 | "protocol": "inspector", 52 | "port": 9001, 53 | "sourceMaps": true 54 | }, 55 | { 56 | "name": "Attach to CLI Debugger", 57 | "type": "node", 58 | "request": "attach", 59 | "protocol": "inspector", 60 | "port": 9002, 61 | "sourceMaps": true 62 | } 63 | ], 64 | "compounds": [ 65 | { 66 | "name": "Extension + Server", 67 | "configurations": ["Launch VS Code Extension", "Attach to TS Server"] 68 | } 69 | ] 70 | } 71 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | // Place your settings in this file to overwrite default and user settings. 2 | { 3 | "editor.tabSize": 2, 4 | "editor.insertSpaces": true, 5 | "editor.rulers": [ 6 | 110 7 | ], 8 | "editor.wordWrapColumn": 110, 9 | "files.trimTrailingWhitespace": true, 10 | "files.insertFinalNewline": true, 11 | "files.exclude": { 12 | "**/.git": true, 13 | "**/.DS_Store": true, 14 | "node_modules": false 15 | }, 16 | "typescript.tsdk": "node_modules/typescript/lib", 17 | "debug.node.autoAttach": "on", 18 | "yaml.schemas": { 19 | "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json": "/syntaxes/*.yaml" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0.0", 3 | "tasks": [ 4 | { 5 | "label": "npm: watch", 6 | "type": "npm", 7 | "script": "watch", 8 | "problemMatcher": { 9 | "owner": "custom", 10 | "pattern": [ 11 | { 12 | "regexp": "never match this please", 13 | "file": 1, 14 | "location": 2, 15 | "message": 3 16 | } 17 | ], 18 | "background": { 19 | "activeOnStart": true, 20 | "beginsPattern": "^\\s*\\[watch\\] build started.*", 21 | "endsPattern": "^\\s*\\[watch\\] build finished.*" 22 | } 23 | }, 24 | "isBackground": true, 25 | "presentation": { 26 | "reveal": "never" 27 | }, 28 | "group": { 29 | "kind": "build", 30 | "isDefault": true 31 | } 32 | }, 33 | { 34 | "label": "sampleWorkspace", 35 | "type": "npm", 36 | "script": "sampleWorkspace:run", 37 | "isBackground": true, 38 | "problemMatcher": { 39 | "owner": "custom", 40 | "pattern": [ 41 | { 42 | "regexp": "never match this please", 43 | "file": 1, 44 | "location": 2, 45 | "message": 3 46 | } 47 | ], 48 | "background": { 49 | "activeOnStart": true, 50 | "beginsPattern": "^\\s*Starting server.*", 51 | "endsPattern": "^\\s*Server ready at.*" 52 | } 53 | } 54 | }, 55 | { 56 | "label": "BuildAndStartWorkspace", 57 | "dependsOn": ["npm: watch", "sampleWorkspace"] 58 | } 59 | ] 60 | } 61 | -------------------------------------------------------------------------------- /.vscodeignore: -------------------------------------------------------------------------------- 1 | .circleci 2 | .vscode 3 | .vscode-test 4 | src 5 | .env 6 | .eslintrc.js 7 | .git 8 | .gitignore 9 | .nvmrc 10 | .prettierrc 11 | .gitattributes 12 | codegen.yml 13 | jest.*.ts 14 | jest.*.js 15 | package-lock.json 16 | tsconfig.build.json 17 | tsconfig.json 18 | node_modules 19 | .git* 20 | CODEOWNERS 21 | *.tsbuildinfo 22 | sampleWorkspace 23 | .changeset 24 | .github 25 | renovate.json 26 | images/**/*.gif 27 | images/marketplace 28 | .yalc 29 | yalc.lock 30 | start-ac.mjs 31 | -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | # This file was automatically generated by the Apollo SecOps team 2 | # Please customize this file as needed prior to merging. 3 | 4 | * @apollographql/client-typescript 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Apollo GraphQL 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /apollo.connectors.mapping.configuration.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": { 3 | "lineComment": "#" 4 | }, 5 | "brackets": [ 6 | ["[", "]"], 7 | ["{", "}"], 8 | ["(", ")"] 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /codegen.yml: -------------------------------------------------------------------------------- 1 | # Would be better to get the schema from the Studio registry once it can be a public variant. 2 | schema: https://graphql.api.apollographql.com/api/graphql 3 | generates: 4 | ./src/language-server/graphqlTypes.ts: 5 | documents: 6 | - src/**/*.ts 7 | - "!src/**/__tests__**/*.ts" 8 | plugins: 9 | - typescript 10 | - typescript-operations 11 | config: 12 | avoidOptionals: true 13 | -------------------------------------------------------------------------------- /graphql.configuration.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": { 3 | "lineComment": "#" 4 | }, 5 | "brackets": [ 6 | ["{", "}"], 7 | ["[", "]"], 8 | ["(", ")"] 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /images/IconRun.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | Exported from Streamline App (https://app.streamlineicons.com) 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /images/apollo.svg: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /images/engine-stats.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apollographql/vscode-graphql/329edefa85a28eca9f0800cb45ca391f76e6eae5/images/engine-stats.png -------------------------------------------------------------------------------- /images/icon-apollo-blue-400x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apollographql/vscode-graphql/329edefa85a28eca9f0800cb45ca391f76e6eae5/images/icon-apollo-blue-400x400.png -------------------------------------------------------------------------------- /images/marketplace/apollo-wordmark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apollographql/vscode-graphql/329edefa85a28eca9f0800cb45ca391f76e6eae5/images/marketplace/apollo-wordmark.png -------------------------------------------------------------------------------- /images/marketplace/autocomplete.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apollographql/vscode-graphql/329edefa85a28eca9f0800cb45ca391f76e6eae5/images/marketplace/autocomplete.gif -------------------------------------------------------------------------------- /images/marketplace/federation-directive-hover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apollographql/vscode-graphql/329edefa85a28eca9f0800cb45ca391f76e6eae5/images/marketplace/federation-directive-hover.png -------------------------------------------------------------------------------- /images/marketplace/jump-to-def.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apollographql/vscode-graphql/329edefa85a28eca9f0800cb45ca391f76e6eae5/images/marketplace/jump-to-def.gif -------------------------------------------------------------------------------- /images/marketplace/perf-annotation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apollographql/vscode-graphql/329edefa85a28eca9f0800cb45ca391f76e6eae5/images/marketplace/perf-annotation.png -------------------------------------------------------------------------------- /images/marketplace/stats.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apollographql/vscode-graphql/329edefa85a28eca9f0800cb45ca391f76e6eae5/images/marketplace/stats.gif -------------------------------------------------------------------------------- /images/marketplace/type-info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apollographql/vscode-graphql/329edefa85a28eca9f0800cb45ca391f76e6eae5/images/marketplace/type-info.png -------------------------------------------------------------------------------- /images/marketplace/warnings-and-errors.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apollographql/vscode-graphql/329edefa85a28eca9f0800cb45ca391f76e6eae5/images/marketplace/warnings-and-errors.gif -------------------------------------------------------------------------------- /images/query-with-vars.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apollographql/vscode-graphql/329edefa85a28eca9f0800cb45ca391f76e6eae5/images/query-with-vars.gif -------------------------------------------------------------------------------- /images/variable-argument-completion.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apollographql/vscode-graphql/329edefa85a28eca9f0800cb45ca391f76e6eae5/images/variable-argument-completion.gif -------------------------------------------------------------------------------- /jest.config.ts: -------------------------------------------------------------------------------- 1 | import type { Config } from "@jest/types"; 2 | 3 | const config: Config.InitialOptions = { 4 | roots: ["/src"], 5 | snapshotFormat: { 6 | escapeString: true, 7 | printBasicPrototype: true, 8 | }, 9 | testMatch: ["**/__tests__/**/*.ts"], 10 | testPathIgnorePatterns: [ 11 | "/node_modules/", 12 | "/fixtures/", 13 | "/snapshotSerializers/", 14 | ], 15 | transform: { 16 | "^.+\\.(ts)$": "ts-jest", 17 | }, 18 | prettierPath: null, 19 | }; 20 | 21 | export default config; 22 | -------------------------------------------------------------------------------- /jest.e2e.config.js: -------------------------------------------------------------------------------- 1 | // see https://github.com/microsoft/vscode-test/issues/37#issuecomment-700167820 2 | const path = require("path"); 3 | 4 | module.exports = { 5 | moduleFileExtensions: ["js", "ts"], 6 | // restrict the roots here so jest doesn't complain about *other* snapshots it sees as obsolete 7 | roots: ["/src/language-server/__e2e__"], 8 | testMatch: ["/src/**/*.e2e.ts"], 9 | testEnvironment: "./src/__e2e__/vscode-environment.js", 10 | setupFiles: ["./src/__e2e__/setup.js"], 11 | verbose: true, 12 | moduleNameMapper: { 13 | vscode: path.join(__dirname, "src", "__e2e__", "vscode.js"), 14 | }, 15 | transform: { 16 | "^.+\\.(ts)$": "ts-jest", 17 | }, 18 | prettierPath: null, 19 | }; 20 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["apollo-open-source"], 3 | "dependencyDashboard": true, 4 | "packageRules": [ 5 | { 6 | "groupName": "all @types", 7 | "groupSlug": "all-types", 8 | "matchPackageNames": ["/@types/*/"] 9 | }, 10 | { 11 | "groupName": "all devDependencies", 12 | "groupSlug": "all-dev", 13 | "matchDepTypes": ["devDependencies"], 14 | "matchPackageNames": ["*"] 15 | }, 16 | { 17 | "groupName": "all dependencies - patch updates", 18 | "groupSlug": "all-patch", 19 | "matchUpdateTypes": ["patch"], 20 | "matchPackageNames": ["*"] 21 | } 22 | ], 23 | "ignoreDeps": [ 24 | "@types/node", 25 | "@types/vscode", 26 | "@typescript-eslint/eslint-plugin", 27 | "@typescript-eslint/parser", 28 | "eslint", 29 | "fractional-indexing" 30 | ] 31 | } 32 | -------------------------------------------------------------------------------- /sampleWorkspace/clientSchema/apollo.config.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | client: { 3 | service: { 4 | name: "clientSchema", 5 | localSchemaFile: "./starwarsSchema.graphql", 6 | }, 7 | includes: ["./src/**/*.js", "./src/**/*.ts", "./src/**/*.tsx"], 8 | excludes: ["**/__tests__/**"], 9 | }, 10 | }; 11 | -------------------------------------------------------------------------------- /sampleWorkspace/clientSchema/src/clientSchema.js: -------------------------------------------------------------------------------- 1 | import gql from "graphql-tag"; 2 | gql` 3 | extend type Droid { 4 | """ 5 | A client-side addition 6 | """ 7 | model: String @deprecated(reason: "It's just a robot...") 8 | } 9 | 10 | extend type Query { 11 | """ 12 | Whether to use defer 13 | """ 14 | featureFlagDefer: Boolean! 15 | } 16 | `; 17 | -------------------------------------------------------------------------------- /sampleWorkspace/clientSchema/src/test.js: -------------------------------------------------------------------------------- 1 | import gql from "graphql-tag"; 2 | gql` 3 | query Test($defer: Boolean!) { 4 | featureFlagDefer @client(always: false) @export(as: "defer") 5 | droid(id: "2000") { 6 | name 7 | model @client 8 | primaryFunction @nonreactive 9 | ... @defer(if: $defer, label: "fc") { 10 | friendsConnection(after: 0, first: 3) @connection(key: "feed") { 11 | friends { 12 | id 13 | } 14 | } 15 | } 16 | } 17 | } 18 | `; 19 | -------------------------------------------------------------------------------- /sampleWorkspace/clientSchema/starwarsSchema.graphql: -------------------------------------------------------------------------------- 1 | ../fixtures/starwarsSchema.graphql -------------------------------------------------------------------------------- /sampleWorkspace/configFileTypes/cjsConfig/apollo.config.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | client: { 3 | service: { 4 | name: "cjsConfig", 5 | localSchemaFile: "./starwarsSchema.graphql", 6 | }, 7 | }, 8 | }; 9 | -------------------------------------------------------------------------------- /sampleWorkspace/configFileTypes/cjsConfig/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test", 3 | "type": "module" 4 | } 5 | -------------------------------------------------------------------------------- /sampleWorkspace/configFileTypes/cjsConfig/src/test.js: -------------------------------------------------------------------------------- 1 | import gql from "graphql-tag"; 2 | gql` 3 | query Test { 4 | droid(id: "2000") { 5 | name 6 | } 7 | } 8 | `; 9 | -------------------------------------------------------------------------------- /sampleWorkspace/configFileTypes/cjsConfig/starwarsSchema.graphql: -------------------------------------------------------------------------------- 1 | ../fixtures/starwarsSchema.graphql -------------------------------------------------------------------------------- /sampleWorkspace/configFileTypes/jsConfigWithCJS/apollo.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | client: { 3 | service: { 4 | name: "jsConfigWithCJS", 5 | localSchemaFile: "./starwarsSchema.graphql", 6 | }, 7 | }, 8 | }; 9 | -------------------------------------------------------------------------------- /sampleWorkspace/configFileTypes/jsConfigWithCJS/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test", 3 | "type": "module" 4 | } 5 | -------------------------------------------------------------------------------- /sampleWorkspace/configFileTypes/jsConfigWithCJS/src/test.js: -------------------------------------------------------------------------------- 1 | import gql from "graphql-tag"; 2 | gql` 3 | query Test { 4 | droid(id: "2000") { 5 | name 6 | } 7 | } 8 | `; 9 | -------------------------------------------------------------------------------- /sampleWorkspace/configFileTypes/jsConfigWithCJS/starwarsSchema.graphql: -------------------------------------------------------------------------------- 1 | ../fixtures/starwarsSchema.graphql -------------------------------------------------------------------------------- /sampleWorkspace/configFileTypes/jsConfigWithESM/apollo.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | client: { 3 | service: { 4 | name: "jsConfigWithESM", 5 | localSchemaFile: "./starwarsSchema.graphql", 6 | }, 7 | }, 8 | }; 9 | -------------------------------------------------------------------------------- /sampleWorkspace/configFileTypes/jsConfigWithESM/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test", 3 | "type": "commonjs" 4 | } 5 | -------------------------------------------------------------------------------- /sampleWorkspace/configFileTypes/jsConfigWithESM/src/test.js: -------------------------------------------------------------------------------- 1 | import gql from "graphql-tag"; 2 | gql` 3 | query Test { 4 | droid(id: "2000") { 5 | name 6 | } 7 | } 8 | `; 9 | -------------------------------------------------------------------------------- /sampleWorkspace/configFileTypes/jsConfigWithESM/starwarsSchema.graphql: -------------------------------------------------------------------------------- 1 | ../fixtures/starwarsSchema.graphql -------------------------------------------------------------------------------- /sampleWorkspace/configFileTypes/mjsConfig/apollo.config.mjs: -------------------------------------------------------------------------------- 1 | export default { 2 | client: { 3 | service: { 4 | name: "mjsConfig", 5 | localSchemaFile: "./starwarsSchema.graphql", 6 | }, 7 | }, 8 | }; 9 | -------------------------------------------------------------------------------- /sampleWorkspace/configFileTypes/mjsConfig/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test", 3 | "type": "commonjs" 4 | } 5 | -------------------------------------------------------------------------------- /sampleWorkspace/configFileTypes/mjsConfig/src/test.js: -------------------------------------------------------------------------------- 1 | import gql from "graphql-tag"; 2 | gql` 3 | query Test { 4 | droid(id: "2000") { 5 | name 6 | } 7 | } 8 | `; 9 | -------------------------------------------------------------------------------- /sampleWorkspace/configFileTypes/mjsConfig/starwarsSchema.graphql: -------------------------------------------------------------------------------- 1 | ../fixtures/starwarsSchema.graphql -------------------------------------------------------------------------------- /sampleWorkspace/configFileTypes/tsConfigWithCJS/apollo.config.ts: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | client: { 3 | service: { 4 | name: "tsConfigWithCJS", 5 | localSchemaFile: "./starwarsSchema.graphql", 6 | }, 7 | }, 8 | }; 9 | -------------------------------------------------------------------------------- /sampleWorkspace/configFileTypes/tsConfigWithCJS/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test", 3 | "type": "module" 4 | } 5 | -------------------------------------------------------------------------------- /sampleWorkspace/configFileTypes/tsConfigWithCJS/src/test.js: -------------------------------------------------------------------------------- 1 | import gql from "graphql-tag"; 2 | gql` 3 | query Test { 4 | droid(id: "2000") { 5 | name 6 | } 7 | } 8 | `; 9 | -------------------------------------------------------------------------------- /sampleWorkspace/configFileTypes/tsConfigWithCJS/starwarsSchema.graphql: -------------------------------------------------------------------------------- 1 | ../fixtures/starwarsSchema.graphql -------------------------------------------------------------------------------- /sampleWorkspace/configFileTypes/tsConfigWithESM/apollo.config.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | client: { 3 | service: { 4 | name: "tsConfigWithESM", 5 | localSchemaFile: "./starwarsSchema.graphql", 6 | }, 7 | }, 8 | }; 9 | -------------------------------------------------------------------------------- /sampleWorkspace/configFileTypes/tsConfigWithESM/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test", 3 | "type": "commonjs" 4 | } 5 | -------------------------------------------------------------------------------- /sampleWorkspace/configFileTypes/tsConfigWithESM/src/test.js: -------------------------------------------------------------------------------- 1 | import gql from "graphql-tag"; 2 | gql` 3 | query Test { 4 | droid(id: "2000") { 5 | name 6 | } 7 | } 8 | `; 9 | -------------------------------------------------------------------------------- /sampleWorkspace/configFileTypes/tsConfigWithESM/starwarsSchema.graphql: -------------------------------------------------------------------------------- 1 | ../fixtures/starwarsSchema.graphql -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/.github/ISSUE_TEMPLATE/connector-bug-report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Connector Bug Report 3 | about: Create a report to help us fix a connector issue 4 | title: "[Connector Name] - Bug Title" 5 | labels: bug 6 | assignees: michael-watson 7 | 8 | --- 9 | 10 | **Connector**: 11 | **Connector Module**: *if any* 12 | 13 | **Describe the bug** 14 | A clear and concise description of what the bug is. 15 | 16 | **To Reproduce** 17 | Steps to reproduce the behavior: 18 | 1. Start [Connector Name] name 19 | 2. Execute this operation: 20 | 21 | ```graphql 22 | query { 23 | 24 | } 25 | ``` 26 | 27 | 3. Results: 28 | 29 | **Expected behavior** 30 | A clear and concise description of what you expected to happen. 31 | 32 | **Screenshots** 33 | If applicable, add screenshots to help explain your problem. 34 | 35 | **Additional context or recommended fixes** 36 | Add any other context about the problem here. 37 | -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/.github/ISSUE_TEMPLATE/new-connector.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: New Connector 3 | about: To create a new connector that is available in the connectors-community 4 | title: "{NAME} Connector" 5 | labels: new 6 | assignees: '' 7 | 8 | --- 9 | 10 | 11 | -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/.github/renovate.json5: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json" 3 | } 4 | -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/.gitignore: -------------------------------------------------------------------------------- 1 | .env 2 | 3 | .DS_Store 4 | */.DS_Store 5 | 6 | node_modules -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": ["apollographql.vscode-apollo","redhat.vscode-yaml"] 3 | } -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "terminal.integrated.profiles.osx": { 3 | "graphos": { 4 | "path": "zsh", 5 | "args": ["-l"], 6 | "env": { 7 | "APOLLO_KEY": "", 8 | "APOLLO_GRAPH_REF": "", 9 | } 10 | } 11 | }, 12 | "terminal.integrated.defaultProfile.osx": "graphos" 13 | } 14 | -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0.0", 3 | "tasks": [{ 4 | "label": "rover dev", 5 | "command": "rover", // Could be any other shell command 6 | "args": ["dev", "--supergraph-config","supergraph.yaml", "--router-config","router.yaml"], 7 | "type": "shell", 8 | "problemMatcher": [], 9 | }] 10 | } -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/apollo.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "rover": { 3 | "supergraphConfig": "./supergraph.yaml" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/.template/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ghcr.io/apollographql/router:v2.2.0 2 | 3 | COPY router.yaml /config.yaml 4 | 5 | CMD ["--config", "/config.yaml"] -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/.template/README: -------------------------------------------------------------------------------- 1 | # {TEMPLATE} REST Connector 2 | 3 | This connector currently covers the {XXX object/functionality} in the {TEMPLATE} API. 4 | 5 | ## Prerequisites 6 | 7 | To use the connector, you need {API key or other prereq}. 8 | 9 | ## Additional Setup for VS Code Task runner 10 | 11 | Edit your `.vscode/settings.json` to include the following keys: 12 | 13 | ``` 14 | { 15 | "terminal.integrated.profiles.osx": { 16 | "graphos": { 17 | "path": "zsh", 18 | "args": ["-l"], 19 | "env": { 20 | "API_KEY": "", 21 | "APOLLO_KEY": "", 22 | ... 23 | } 24 | } 25 | }, 26 | "terminal.integrated.defaultProfile.osx": "graphos" 27 | } 28 | ``` 29 | 30 | Once you've set this up, you can execute the `Tasks: Run Task` command in VS Code to run the `rover dev` task. 31 | Alternatively, you can open a new terminal window in VS Code with the `graphos` profile, then run `rover dev --supergraph-config supergraph.yaml --router-config router.yaml`. 32 | 33 | ## Contributing 34 | 35 | 36 | The following schema modules can be added to this connector: 37 | 38 | - Example 1 39 | - Example 2 40 | 41 | To contribute them, make sure to: 42 | 43 | 1. Add a schema designed for the module as a new `.graphql` file. 44 | 2. Update the `router.yaml` and `supergraph.yaml` files accordingly. 45 | 46 | See [REST API reference]() for other modules that can be implemented. You can use the current modules in this folder as examples to work with. -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/.template/connector.graphql: -------------------------------------------------------------------------------- 1 | extend schema 2 | @link(url: "https://specs.apollo.dev/federation/v2.10", import: ["@key", "@requires"]) 3 | @link( 4 | url: "https://specs.apollo.dev/connect/v0.2" 5 | import: ["@source", "@connect"] 6 | ) 7 | @source( 8 | name: "jsonPlaceholder" 9 | http: { 10 | baseURL: "https://jsonplaceholder.typicode.com/" 11 | } 12 | ) 13 | 14 | type Post { 15 | id: ID! 16 | body: String 17 | title: String 18 | } 19 | 20 | type Query { 21 | posts: [Post] 22 | @connect( 23 | source: "jsonPlaceholder" 24 | http: { GET: "/posts" } 25 | selection: """ 26 | id 27 | title 28 | body 29 | """ 30 | ) 31 | } -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/.template/router.yaml: -------------------------------------------------------------------------------- 1 | supergraph: 2 | listen: 0.0.0.0:${env.PORT:-4000} 3 | 4 | headers: 5 | all: 6 | request: 7 | - propagate: 8 | matching: .* 9 | telemetry: 10 | instrumentation: 11 | spans: 12 | mode: spec_compliant 13 | 14 | # connectors: 15 | # sources: 16 | # connectorName.sourceName: 17 | # $config: 18 | # apiKey: ${env.API_KEY} -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/.template/supergraph.yaml: -------------------------------------------------------------------------------- 1 | federation_version: =2.11.0 2 | subgraphs: 3 | connector: 4 | routing_url: http://connector 5 | schema: 6 | file: connector.graphql 7 | -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/JSONPlaceholder/README: -------------------------------------------------------------------------------- 1 | # JSONPlaceholder REST Connector 2 | 3 | This connector brings [{JSON} Placeholder](https://jsonplaceholder.typicode.com/), which provides fake data for testing and prototyping to GraphQL! 4 | 5 | The GET operation has been implemented for 6 | 7 | - Users 8 | - ToDos 9 | - Posts 10 | - Comments 11 | - Albums 12 | - Photos -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/JSONPlaceholder/albums.graphql: -------------------------------------------------------------------------------- 1 | extend schema 2 | @link( 3 | url: "https://specs.apollo.dev/federation/v2.10" 4 | import: ["@key"] 5 | ) 6 | @link( 7 | url: "https://specs.apollo.dev/connect/v0.2" 8 | import: ["@connect", "@source"] 9 | ) 10 | # A @source directive defines a shared data source for multiple connectors. 11 | @source( 12 | name: "JSONPlaceholder" 13 | http: { baseURL: "https://jsonplaceholder.typicode.com/" } 14 | ) 15 | 16 | type Album @key(fields: "id") { 17 | id: ID! 18 | userId: ID! 19 | title: String 20 | } 21 | 22 | type User @key(fields: "id") { 23 | id: ID! 24 | albums: [Album] 25 | @connect( 26 | source: "JSONPlaceholder" 27 | http: { GET: "/users/{$this.id}/albums" } 28 | selection: """ 29 | id 30 | userId 31 | title 32 | """ 33 | ) 34 | } 35 | 36 | type Query { 37 | getAlbum(id: ID!): Album 38 | @connect( 39 | source: "JSONPlaceholder" 40 | http: { GET: "/albums/{$args.id}" } 41 | selection: """ 42 | id 43 | userId 44 | title 45 | """ 46 | entity: true 47 | ) 48 | } -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/JSONPlaceholder/comments.graphql: -------------------------------------------------------------------------------- 1 | extend schema 2 | @link( 3 | url: "https://specs.apollo.dev/federation/v2.10" 4 | import: ["@key"] 5 | ) 6 | @link( 7 | url: "https://specs.apollo.dev/connect/v0.2" 8 | import: ["@connect", "@source"] 9 | ) 10 | # A @source directive defines a shared data source for multiple connectors. 11 | @source( 12 | name: "JSONPlaceholder" 13 | http: { baseURL: "https://jsonplaceholder.typicode.com/" } 14 | ) 15 | 16 | type Comment { 17 | id: ID! 18 | postId: ID! 19 | name: String 20 | email: String 21 | body: String 22 | } 23 | 24 | type Post @key(fields: "id") { 25 | id: ID! 26 | comments: [Comment] 27 | @connect( 28 | source: "JSONPlaceholder" 29 | http: { GET: "/posts/{$this.id}/comments" } 30 | selection: """ 31 | id 32 | postId 33 | name 34 | email 35 | body 36 | """ 37 | ) 38 | } 39 | 40 | type Query { 41 | getComment(id: ID!): Comment 42 | @connect( 43 | source: "JSONPlaceholder" 44 | http: { GET: "/comments/{$args.id}" } 45 | selection: """ 46 | id 47 | postId 48 | name 49 | email 50 | body 51 | """ 52 | entity: true 53 | ) 54 | } -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/JSONPlaceholder/photos.graphql: -------------------------------------------------------------------------------- 1 | extend schema 2 | @link( 3 | url: "https://specs.apollo.dev/federation/v2.10" 4 | import: ["@key"] 5 | ) 6 | @link( 7 | url: "https://specs.apollo.dev/connect/v0.2" 8 | import: ["@connect", "@source"] 9 | ) 10 | # A @source directive defines a shared data source for multiple connectors. 11 | @source( 12 | name: "JSONPlaceholder" 13 | http: { baseURL: "https://jsonplaceholder.typicode.com/" } 14 | ) 15 | 16 | type Photo { 17 | id: ID! 18 | albumId: ID! 19 | title: String 20 | url: String 21 | thumbnailUrl: String 22 | } 23 | 24 | type Album @key(fields: "id") { 25 | id: ID! 26 | photos: [Photo] 27 | @connect( 28 | source: "JSONPlaceholder" 29 | http: { GET: "/albums/{$this.id}/photos" } 30 | selection: """ 31 | id 32 | albumId 33 | title 34 | url 35 | thumbnailUrl 36 | """ 37 | ) 38 | } 39 | 40 | type Query { 41 | getPhoto(id: ID!): Photo 42 | @connect( 43 | source: "JSONPlaceholder" 44 | http: { GET: "/photos/{$args.id}" } 45 | selection: """ 46 | id 47 | albumId 48 | title 49 | url 50 | thumbnailUrl 51 | """ 52 | entity: true 53 | ) 54 | } -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/JSONPlaceholder/posts.graphql: -------------------------------------------------------------------------------- 1 | extend schema 2 | @link( 3 | url: "https://specs.apollo.dev/federation/v2.10" 4 | import: ["@key"] 5 | ) 6 | @link( 7 | url: "https://specs.apollo.dev/connect/v0.2" 8 | import: ["@connect", "@source"] 9 | ) 10 | # A @source directive defines a shared data source for multiple connectors. 11 | @source( 12 | name: "JSONPlaceholder" 13 | http: { baseURL: "https://jsonplaceholder.typicode.com/" } 14 | ) 15 | 16 | type Post @key(fields: "id") { 17 | id: ID! 18 | userId: ID! 19 | title: String 20 | body: String 21 | } 22 | 23 | type User @key(fields: "id") { 24 | id: ID! 25 | posts: [Post] 26 | @connect( 27 | source: "JSONPlaceholder" 28 | http: { GET: "/users/{$this.id}/posts" } 29 | selection: """ 30 | id 31 | userId 32 | title 33 | body 34 | """ 35 | ) 36 | } 37 | 38 | type Query { 39 | getPost(id: ID!): Post 40 | @connect( 41 | source: "JSONPlaceholder" 42 | http: { GET: "/posts/{$args.id}" } 43 | selection: """ 44 | id 45 | userId 46 | title 47 | body 48 | """ 49 | entity: true 50 | ) 51 | } -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/JSONPlaceholder/supergraph.yaml: -------------------------------------------------------------------------------- 1 | federation_version: =2.11.0 2 | subgraphs: 3 | users: 4 | routing_url: http://ignored 5 | schema: 6 | file: users.graphql 7 | todos: 8 | routing_url: http://ignored 9 | schema: 10 | file: todos.graphql 11 | posts: 12 | routing_url: http://ignored 13 | schema: 14 | file: posts.graphql 15 | comments: 16 | routing_url: http://ignored 17 | schema: 18 | file: comments.graphql 19 | albums: 20 | routing_url: http://ignored 21 | schema: 22 | file: albums.graphql 23 | photos: 24 | routing_url: http://ignored 25 | schema: 26 | file: photos.graphql 27 | -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/JSONPlaceholder/todos.graphql: -------------------------------------------------------------------------------- 1 | extend schema 2 | @link( 3 | url: "https://specs.apollo.dev/federation/v2.10" 4 | import: ["@key"] 5 | ) 6 | @link( 7 | url: "https://specs.apollo.dev/connect/v0.2" 8 | import: ["@connect", "@source"] 9 | ) 10 | # A @source directive defines a shared data source for multiple connectors. 11 | @source( 12 | name: "JSONPlaceholder" 13 | http: { baseURL: "https://jsonplaceholder.typicode.com/" } 14 | ) 15 | 16 | type ToDo { 17 | id: ID! 18 | userId: ID! 19 | title: String 20 | completed: Boolean 21 | } 22 | 23 | type User @key(fields: "id") { 24 | id: ID! 25 | todos: [ToDo] 26 | @connect( 27 | source: "JSONPlaceholder" 28 | http: { GET: "/users/{$this.id}/todos" } 29 | selection: """ 30 | id 31 | userId 32 | title 33 | completed 34 | """ 35 | ) 36 | } 37 | 38 | type Query { 39 | getToDo(id: ID!): ToDo 40 | @connect( 41 | source: "JSONPlaceholder" 42 | http: { GET: "/todos/{$args.id}" } 43 | selection: """ 44 | id 45 | userId 46 | title 47 | completed 48 | """ 49 | entity: true 50 | ) 51 | } -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/JSONPlaceholder/users.graphql: -------------------------------------------------------------------------------- 1 | 2 | # These are the necessary federation and connector directives you will be using 3 | extend schema 4 | @link( 5 | url: "https://specs.apollo.dev/federation/v2.10" 6 | import: ["@key"] 7 | ) 8 | @link( 9 | url: "https://specs.apollo.dev/connect/v0.2" 10 | import: ["@connect", "@source"] 11 | ) 12 | # A @source directive defines a shared data source for multiple connectors. 13 | @source( 14 | name: "JSONPlaceholder" 15 | http: { baseURL: "https://jsonplaceholder.typicode.com/" } 16 | ) 17 | 18 | type User @key(fields: "id") { 19 | id: ID! 20 | name: String 21 | username: String 22 | email: String 23 | address: Address 24 | phone: String 25 | website: String 26 | company: Company 27 | } 28 | 29 | 30 | type Address { 31 | line1: String 32 | line2: String 33 | city: String 34 | zip: String 35 | geo: Geo 36 | } 37 | 38 | type Geo { 39 | lat: String 40 | lng: String 41 | } 42 | 43 | type Company { 44 | name: String 45 | catchPhrase: String 46 | bs: String 47 | } 48 | 49 | type Query { 50 | getUser(id: ID!): User 51 | # A @connect directive defines the API data source of a GraphQL schema field. 52 | @connect( 53 | source: "JSONPlaceholder" 54 | http: { GET: "/users/{$args.id}" } 55 | selection: """ 56 | id 57 | name 58 | username 59 | email 60 | address: $.address { 61 | line1: street 62 | line2: suite 63 | city 64 | zip: zipcode 65 | geo: $.geo { 66 | lat 67 | lng 68 | } 69 | } 70 | phone 71 | website 72 | company: $.company { 73 | name 74 | catchPhrase 75 | bs 76 | } 77 | """ 78 | entity: true 79 | ) 80 | } 81 | -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/TM-Forum/README.md: -------------------------------------------------------------------------------- 1 | # [TM Forum](https://www.tmforum.org/) Connector 2 | 3 | This connector currently only covers [TMF622 Product Ordering](https://github.com/tmforum-apis/TMF622_ProductOrder/blob/master/TMF622-ProductOrder-v4.0.0.swagger.json). 4 | 5 | ## Additional Setup for VS Code Task runner 6 | 7 | ## Contributing 8 | 9 | Any of the other TM Forum APIs can be contributed, just name the schema file in a format: tmfXXX-{TMF_NAME}.graphql -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/TM-Forum/router.yaml: -------------------------------------------------------------------------------- 1 | supergraph: 2 | listen: 127.0.0.1:4000 3 | 4 | headers: 5 | all: 6 | request: 7 | - propagate: 8 | matching: .* 9 | telemetry: 10 | instrumentation: 11 | spans: 12 | mode: spec_compliant 13 | 14 | # connectors: 15 | # subgraphs: 16 | # connector: 17 | # $config: 18 | # api: ${env.API_KEY} -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/TM-Forum/supergraph.yaml: -------------------------------------------------------------------------------- 1 | federation_version: =2.11.0 2 | subgraphs: 3 | connector: 4 | routing_url: http://connector 5 | schema: 6 | file: connector.graphql 7 | -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/adobe-commerce-cloud/README.md: -------------------------------------------------------------------------------- 1 | # Adobe Commerce Cloud REST Connector 2 | 3 | This connector is an example of how you could connecto to Magento Adobe Commerce Cloud instance. We were unable to validate all aspects of this connector due to an error warming up the local instance. We are working on getting a running instance to validate against. 4 | 5 | Error: https://experienceleague.adobe.com/en/docs/commerce-knowledge-base/kb/troubleshooting/miscellaneous/error-warming-up-failed-on-magento-commerce-cloud 6 | 7 | In the short term, we used `prism mock ./swagger.json` to mock out the local API contents. -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/adobe-commerce-cloud/addresses.graphql: -------------------------------------------------------------------------------- 1 | extend schema 2 | @link(url: "https://specs.apollo.dev/federation/v2.10") 3 | @link(url: "https://specs.apollo.dev/connect/v0.2", import: ["@connect", "@source"]) 4 | @source( 5 | name: "magento" 6 | http: { 7 | # https://developer.adobe.com/commerce/webapi/rest/quick-reference/ 8 | baseURL: "http://127.0.0.1:4010/V1" 9 | headers: [ 10 | { name: "Content-Type", value: "application/json" } 11 | { name: "Authorization", from: "Authorization" } 12 | ] 13 | } 14 | ) 15 | 16 | type Mutation { 17 | """ 18 | Delete customer address by ID. 19 | Returns true on success. 20 | """ 21 | deleteAddress(addressId: ID!): Boolean! 22 | @connect( 23 | source: "magento" 24 | http: { 25 | DELETE: "/addresses/{$args.addressId}" 26 | } 27 | # https://adobe-commerce.redoc.ly/2.4.7-admin/tag/addressesaddressId#operation/DeleteV1AddressesAddressId 28 | selection: "data.deleteAddress" 29 | ) 30 | } -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/adobe-commerce-cloud/customer.graphql: -------------------------------------------------------------------------------- 1 | extend schema 2 | @link(url: "https://specs.apollo.dev/federation/v2.10") 3 | @link( 4 | url: "https://specs.apollo.dev/connect/v0.2" 5 | import: ["@source", "@connect"] 6 | ) 7 | @source( 8 | name: "magento" 9 | http: { 10 | # https://developer.adobe.com/commerce/webapi/rest/quick-reference/ 11 | baseURL: "http://127.0.0.1:4010/V1" 12 | headers: [ 13 | { name: "Content-Type", value: "application/json" } 14 | { name: "Authorization", from: "Authorization" } 15 | ] 16 | } 17 | ) 18 | 19 | type Query { 20 | customer(id: ID!): Customer 21 | @connect( 22 | source: "magento" 23 | http: { 24 | GET: "/customers/{$args.id}" 25 | } 26 | selection: """ 27 | # https://adobe-commerce.redoc.ly/2.4.7-admin/tag/customerscustomerId#operation/GetV1CustomersCustomerId 28 | id 29 | email 30 | firstname 31 | lastname 32 | # Select other customer fields as needed 33 | """ 34 | entity: true 35 | ) 36 | } 37 | 38 | type Mutation { 39 | createCustomer(input: CustomerInput!): Customer 40 | @connect( 41 | source: "magento" 42 | http: { 43 | POST: "/customers" 44 | body: """ 45 | $args.input { 46 | email 47 | firstname 48 | lastname 49 | # Map other customer fields as needed 50 | } 51 | """ 52 | } 53 | selection: """ 54 | # https://adobe-commerce.redoc.ly/2.4.7-admin/tag/customers#operation/PostV1Customers 55 | id 56 | email 57 | firstname 58 | lastname 59 | # Select other customer fields as needed 60 | """ 61 | ) 62 | } 63 | 64 | type Customer { 65 | id: ID! 66 | email: String! 67 | firstname: String! 68 | lastname: String! 69 | # Add other customer fields as needed 70 | } 71 | 72 | input CustomerInput { 73 | email: String! 74 | firstname: String! 75 | lastname: String! 76 | # Add other input fields as needed 77 | } -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/adobe-commerce-cloud/products.graphql: -------------------------------------------------------------------------------- 1 | extend schema 2 | @link(url: "https://specs.apollo.dev/federation/v2.10") 3 | @link( 4 | url: "https://specs.apollo.dev/connect/v0.2" 5 | import: ["@source", "@connect"] 6 | ) 7 | @source( 8 | name: "magento" 9 | http: { 10 | # https://developer.adobe.com/commerce/webapi/rest/quick-reference/ 11 | baseURL: "http://127.0.0.1:4010/V1" 12 | headers: [ 13 | { name: "Content-Type", value: "application/json" } 14 | { name: "Authorization", from: "Authorization" } 15 | ] 16 | } 17 | ) 18 | type Query { 19 | products: [Product] 20 | @connect( 21 | source: "magento" 22 | http: { GET: "/products" } 23 | selection: """ 24 | $.items { 25 | sku 26 | price 27 | weight 28 | } 29 | """ 30 | ) 31 | } 32 | 33 | type Mutation { 34 | createProduct(product: ProductInput): Product 35 | @connect( 36 | source: "magento" 37 | http: { 38 | PUT: "/products/{$args.product.sku}" 39 | body: """ 40 | product: $args.product 41 | """ 42 | } 43 | selection: """ 44 | sku 45 | price 46 | weight 47 | """ 48 | ) 49 | deleteProduct(sku: ID!): Boolean 50 | @connect( 51 | source: "magento" 52 | http: { DELETE: "/products/{$args.sku}" } 53 | selection: """ 54 | $ 55 | """ 56 | ) 57 | } 58 | 59 | input ProductInput { 60 | sku: ID! 61 | name: String 62 | price: Float 63 | weight: Float 64 | } 65 | 66 | type Product { 67 | sku: String 68 | price: Float 69 | weight: Float 70 | } 71 | -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/adobe-commerce-cloud/router.yaml: -------------------------------------------------------------------------------- 1 | supergraph: 2 | listen: 127.0.0.1:4000 3 | 4 | headers: 5 | all: 6 | request: 7 | - propagate: 8 | matching: .* 9 | telemetry: 10 | instrumentation: 11 | spans: 12 | mode: spec_compliant 13 | 14 | # connectors: 15 | # subgraphs: 16 | # addresses: 17 | # $config: 18 | # apiKey: ${env.ADOBE_COMMERCE_CLOUD_API_KEY} 19 | # customer: 20 | # $config: 21 | # apiKey: ${env.ADOBE_COMMERCE_CLOUD_API_KEY} 22 | # products: 23 | # $config: 24 | # apiKey: ${env.ADOBE_COMMERCE_CLOUD_API_KEY} -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/adobe-commerce-cloud/supergraph.yaml: -------------------------------------------------------------------------------- 1 | federation_version: =2.11.0 2 | subgraphs: 3 | addresses: 4 | routing_url: http://addresses 5 | schema: 6 | file: addresses.graphql 7 | customer: 8 | routing_url: http://customer 9 | schema: 10 | file: customer.graphql 11 | products: 12 | routing_url: http://products 13 | schema: 14 | file: products.graphql 15 | -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/anthropic/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ghcr.io/apollographql/router:v2.2.0 2 | 3 | COPY router.yaml /config.yaml 4 | 5 | CMD ["--config", "/config.yaml"] -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/anthropic/router.yaml: -------------------------------------------------------------------------------- 1 | supergraph: 2 | listen: 0.0.0.0:${env.PORT:-4000} 3 | 4 | headers: 5 | all: 6 | request: 7 | - propagate: 8 | matching: .* 9 | telemetry: 10 | instrumentation: 11 | spans: 12 | mode: spec_compliant 13 | 14 | connectors: 15 | sources: 16 | messages.anthropic: 17 | $config: 18 | apiKey: ${env.ANTHROPOIC_API_KEY} -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/anthropic/supergraph.yaml: -------------------------------------------------------------------------------- 1 | federation_version: =2.11.0 2 | subgraphs: 3 | messages: 4 | routing_url: http://messages 5 | schema: 6 | file: messages.graphql 7 | -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/apollo-ecomm-simple/README: -------------------------------------------------------------------------------- 1 | # Apollo EComm connector 2 | 3 | This is based on the [Apollo getting started guide](https://www.apollographql.com/docs/graphos/get-started/guides/rest#step-2-connect-rest-apis) connector and is used for free API access to learn. -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/apollo-ecomm-simple/connector.graphql: -------------------------------------------------------------------------------- 1 | 2 | # These are the necessary federation and connector directives you will be using 3 | extend schema 4 | @link( 5 | url: "https://specs.apollo.dev/federation/v2.10" 6 | import: ["@key"] 7 | ) 8 | @link( 9 | url: "https://specs.apollo.dev/connect/v0.2" 10 | import: ["@connect", "@source"] 11 | ) 12 | # A @source directive defines a shared data source for multiple connectors. 13 | @source( 14 | name: "ecomm" 15 | http: { baseURL: "https://ecommerce.demo-api.apollo.dev/" } 16 | ) 17 | 18 | type Product { 19 | id: ID! 20 | name: String 21 | description: String 22 | } 23 | 24 | type Query { 25 | products: [Product] 26 | # A @connect directive defines the API data source of a GraphQL schema field. 27 | @connect( 28 | source: "ecomm" 29 | http: { GET: "/products" } 30 | selection: """ 31 | $.products { 32 | id 33 | name 34 | description 35 | } 36 | """ 37 | ) 38 | } -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/apollo-ecomm-simple/router.yaml: -------------------------------------------------------------------------------- 1 | supergraph: 2 | listen: 0.0.0.0:${env.PORT:-4000} 3 | 4 | headers: 5 | all: 6 | request: 7 | - propagate: 8 | matching: .* 9 | telemetry: 10 | instrumentation: 11 | spans: 12 | mode: spec_compliant 13 | 14 | # connectors: 15 | # subgraphs: 16 | # connector: 17 | # $config: 18 | # apiKey: ${env.API_KEY} -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/apollo-ecomm-simple/supergraph.yaml: -------------------------------------------------------------------------------- 1 | federation_version: =2.11.0 2 | subgraphs: 3 | connector: 4 | routing_url: http://connector 5 | schema: 6 | file: connector.graphql 7 | -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/apple/README: -------------------------------------------------------------------------------- 1 | # Apple App Store Connect API REST Connector 2 | 3 | This connector currently covers the App object with builds and price points in the App Store Connect API. To use this, you'll need to add a `API_KEY` in your environment variables then running `rover` or the `router` with the config files in this folder. 4 | 5 | ## Additional Setup for VS Code Task runner 6 | 7 | Edit your `.vscode/settings.json` to include the Strapi specific keys 8 | 9 | ``` 10 | { 11 | "terminal.integrated.profiles.osx": { 12 | "graphos": { 13 | "path": "zsh", 14 | "args": ["-l"], 15 | "env": { 16 | "API_KEY": "", 17 | "APOLLO_KEY": "", 18 | ... 19 | } 20 | } 21 | }, 22 | "terminal.integrated.defaultProfile.osx": "graphos" 23 | } 24 | 25 | ``` 26 | 27 | Then you can execute the "Tasks: Run Task" command in VS code to execute the `rover dev` task or simply open a new terminal window in vscode with the `graphos` profile, then you can simply run `rover dev --supergraph-config supergraph.yaml --router-config router.yaml`. 28 | 29 | ## Contributing 30 | 31 | The following schema modules need to be: 32 | 33 | 1. A schema designed for that portion of the rest API as a new `.graphql` file 34 | 2. Additions to the `router.yaml` and `supergraph.yaml` files 35 | 36 | There are various modules that can be implemented and can be found in the [documentation navigation](https://developer.apple.com/documentation/) bar -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/apple/app-store-connect.graphql: -------------------------------------------------------------------------------- 1 | extend schema 2 | @link( 3 | url: "https://specs.apollo.dev/federation/v2.10" 4 | import: ["@key", "@requires"] 5 | ) 6 | @link( 7 | url: "https://specs.apollo.dev/connect/v0.2" 8 | import: ["@source", "@connect"] 9 | ) 10 | @source( 11 | name: "connect-api" 12 | http: { 13 | # https://developer.apple.com/documentation/appstoreconnectapi 14 | # https://developer.apple.com/sample-code/app-store-connect/app-store-connect-openapi-specification.zip 15 | baseURL: "https://api.appstoreconnect.apple.com/v1" 16 | headers: [{ name: "Authorization", value: "Bearer {$config.apiKey}" }] 17 | } 18 | ) 19 | 20 | type App { 21 | id: ID! 22 | name: String 23 | bundleId: String 24 | sku: String 25 | builds: [Build] 26 | @connect( 27 | source: "connect-api" 28 | http: { GET: "/apps/{$this.id}/builds" } 29 | selection: """ 30 | $.data { 31 | id 32 | $.attributes { 33 | version 34 | expired 35 | minOsVersion 36 | } 37 | } 38 | """ 39 | ) 40 | pricePoints: [AppPricePoint] 41 | @connect( 42 | source: "connect-api" 43 | http: { GET: "/apps/{$this.id}/appPricePoints" } 44 | selection: """ 45 | $.data { 46 | id 47 | $.attributes { 48 | customerPrice 49 | proceeds 50 | } 51 | } 52 | """ 53 | ) 54 | } 55 | 56 | type AppPricePoint { 57 | id: ID! 58 | customerPrice: String 59 | proceeds: String 60 | } 61 | 62 | type Build { 63 | id: ID! 64 | expired: Boolean 65 | version: String 66 | minOsVersion: String 67 | } 68 | 69 | type Query { 70 | apps: [App] 71 | @connect( 72 | source: "connect-api" 73 | http: { GET: "/apps" } 74 | selection: """ 75 | $.data { 76 | id 77 | $.attributes { 78 | name 79 | bundleId 80 | sku 81 | } 82 | } 83 | """ 84 | ) 85 | app(id: ID!): App 86 | @connect( 87 | source: "connect-api" 88 | http: { GET: "/apps/{$args.id}" } 89 | selection: """ 90 | $.data { 91 | id 92 | $.attributes { 93 | name 94 | bundleId 95 | sku 96 | } 97 | } 98 | """ 99 | ) 100 | } 101 | -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/apple/router.yaml: -------------------------------------------------------------------------------- 1 | supergraph: 2 | listen: 0.0.0.0:${env.PORT:-4000} 3 | 4 | headers: 5 | all: 6 | request: 7 | - propagate: 8 | matching: .* 9 | telemetry: 10 | instrumentation: 11 | spans: 12 | mode: spec_compliant 13 | 14 | connectors: 15 | subgraphs: 16 | app-store-connect: 17 | $config: 18 | apiKey: ${env.API_KEY} -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/apple/supergraph.yaml: -------------------------------------------------------------------------------- 1 | federation_version: =2.11.0 2 | subgraphs: 3 | app-store-connect: 4 | routing_url: http://app-store-connect 5 | schema: 6 | file: app-store-connect.graphql 7 | -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/aws/json-responses/product-price.json: -------------------------------------------------------------------------------- 1 | { 2 | "default_price": 35000, 3 | "is_active": true, 4 | "currency": "usd", 5 | "billing_schema": "per_unit", 6 | "recurring": { 7 | "interval": 0, 8 | "interval_count": 3 9 | } 10 | } -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/aws/router.yaml: -------------------------------------------------------------------------------- 1 | supergraph: 2 | listen: 0.0.0.0:${env.PORT:-4000} 3 | 4 | headers: 5 | all: 6 | request: 7 | - propagate: 8 | matching: .* 9 | telemetry: 10 | instrumentation: 11 | spans: 12 | mode: spec_compliant 13 | connectors: 14 | preview_connect_v0_2: true 15 | authentication: 16 | connector: 17 | sources: 18 | aws-lambda.lambda: 19 | aws_sig_v4: 20 | default_chain: 21 | # You can also set AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY as environment variables 22 | # Docs: https://www.apollographql.com/docs/graphos/routing/security/subgraph-authentication#default-chain-authentication 23 | profile_name: "default" #name of profile in .aws/configuration file 24 | region: "us-east-1" 25 | service_name: "lambda" 26 | # assume_role: 27 | # role_arn: "arn:aws:iam::{accountId}:role/{roleName}" 28 | # session_name: "connector" 29 | aws-dynamodb.dynamodb: 30 | aws_sig_v4: 31 | default_chain: 32 | # You can also set AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY as environment variables 33 | # Docs: https://www.apollographql.com/docs/graphos/routing/security/subgraph-authentication#default-chain-authentication 34 | profile_name: "default" #name of profile in .aws/configuration file 35 | region: "us-east-1" 36 | service_name: "dynamodb" 37 | # assume_role: 38 | # role_arn: "arn:aws:iam::{accountId}:role/{roleName}" 39 | # session_name: "connector" 40 | 41 | ## If you want to override the url to use dynamic urls based on environment variables 42 | # connectors: 43 | # subgraphs: 44 | # dynamodb: # The name of the subgraph 45 | # sources: 46 | # address: # Refers to @source(name: "v1") 47 | # override_url: ${env.DYNAMODB_URL:-https://dynamodb.us-east-1.amazonaws.com} 48 | # # $config: #<- if you wanted to have environment variables used in schema file (i.e. {$config.apiKey}) 49 | # # apiKey: ${env.API_KEY} 50 | # lambda: 51 | # sources: 52 | # lambda: 53 | # override_url: ${env.LAMBDA_URL:-https://lambda.us-east-1.amazonaws.com} 54 | 55 | -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/aws/supergraph.yaml: -------------------------------------------------------------------------------- 1 | federation_version: =2.11.0 2 | subgraphs: 3 | aws-lambda: 4 | routing_url: http://lambda 5 | schema: 6 | file: lambda.graphql 7 | aws-dynamodb: 8 | routing_url: http://dynamodb 9 | schema: 10 | file: dynamodb.graphql 11 | -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/bored/README.md: -------------------------------------------------------------------------------- 1 | # Bored API REST Connector 2 | 3 | This connector covers the full [Bored API](https://bored-api.appbrewery.com/). This is an API that retrieves random activites. 4 | 5 | This API is considered a teaching tool and is best used for practice with Connectors. It has no business or production value, but sometimes that's nice. 6 | 7 | API Requests are rate limited to 100 requests every 15 minutes. 8 | 9 | ## Additional Setup for VS Code Task runner 10 | 11 | Edit your `.vscode/settings.json` to include the following keys: 12 | 13 | ``` 14 | { 15 | "terminal.integrated.profiles.osx": { 16 | "graphos": { 17 | "path": "zsh", 18 | "args": ["-l"], 19 | "env": { 20 | "API_KEY": "", 21 | "APOLLO_KEY": "", 22 | ... 23 | } 24 | } 25 | }, 26 | "terminal.integrated.defaultProfile.osx": "graphos" 27 | } 28 | ``` 29 | 30 | Once you've set this up, you can execute the `Tasks: Run Task` command in VS Code to run the `rover dev` task. 31 | Alternatively, you can open a new terminal window in VS Code with the `graphos` profile, then run `rover dev --supergraph-config supergraph.yaml --router-config router.yaml`. 32 | 33 | ## Contributing 34 | 35 | This conector will not evolve, however, contributions of other REST API connectors are welcome. Please see the [Contribution Guide](https://github.com/apollographql/connectors-community/tree/main?tab=readme-ov-file#contributing-a-connector-to-the-community) 36 | -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/bored/bored.graphql: -------------------------------------------------------------------------------- 1 | extend schema 2 | @link( 3 | url: "https://specs.apollo.dev/federation/v2.11" 4 | import: ["@key", "@shareable", "@external"] 5 | ) # Enable this schema to use Apollo Federation features 6 | @link( # Enable this schema to use Apollo Connectors 7 | url: "https://specs.apollo.dev/connect/v0.2" 8 | import: ["@connect", "@source"] 9 | ) 10 | @source(name: "bored", http: { baseURL: "https://bored-api.appbrewery.com" }) 11 | type Query { 12 | getRandomActivity: Activity 13 | @connect( 14 | source: "bored" 15 | http: { GET: "/random" } 16 | selection: """ 17 | activity 18 | availability 19 | type 20 | participants 21 | price 22 | accessibility 23 | duration 24 | kidFriendly 25 | link 26 | key 27 | """ 28 | ) 29 | 30 | getActivityByType(type: ActivityType!): [Activity] 31 | @connect( 32 | source: "bored" 33 | http: { 34 | GET: "/filter" 35 | queryParams: """ 36 | type: $args.type->match( 37 | ["EDUCATION", "education"], 38 | ["RECREATIONAL", "recreational"], 39 | ["SOCIAL", "social"], 40 | ["DIY", "diy"], 41 | ["CHARITY", "charity"], 42 | ["COOKING", "cooking"], 43 | ["RELAXATION", "relaxation"], 44 | ["MUSIC", "music"], 45 | ["BUSYWORK", "busywork"] 46 | ) 47 | """ 48 | } 49 | selection: """ 50 | activity 51 | availability 52 | type 53 | participants 54 | price 55 | accessibility 56 | duration 57 | kidFriendly 58 | link 59 | key 60 | """ 61 | ) 62 | } 63 | 64 | type Activity { 65 | activity: String 66 | availability: Float 67 | type: String 68 | participants: Int 69 | price: Float 70 | accessibility: String 71 | duration: String 72 | kidFriendly: Boolean 73 | link: String 74 | key: String 75 | } 76 | 77 | enum ActivityType { 78 | EDUCATION 79 | RECREATIONAL 80 | SOCIAL 81 | DIY 82 | CHARITY 83 | COOKING 84 | RELAXATION 85 | MUSIC 86 | BUSYWORK 87 | } 88 | -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/bored/supergraph.yaml: -------------------------------------------------------------------------------- 1 | subgraphs: 2 | bored: 3 | routing_url: http://localhost:4000 4 | schema: 5 | file: bored.graphql 6 | federation_version: =2.11.0 -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/common-room/README.md: -------------------------------------------------------------------------------- 1 | # Common Room REST Connector 2 | 3 | This connector currently covers the Contact object in Common Room](https://api.commonroom.io/docs/) REST API. To use this, you'll need to add a `COMMON_ROOM_API_KEY` in your environment variables then running `rover` or the `router` binary with the config files in this folder (`router.yaml` and `supergraph.yaml`). 4 | 5 | ## Contributing 6 | 7 | A partial implementation of the `Contacts` API has been implemented including: 8 | 9 | - GET contact by email 10 | - POST add note to contact 11 | 12 | The following schema modules still need to be implemented: 13 | 14 | - Activities 15 | - Segments 16 | - Tags 17 | - Right to be Forgotten 18 | 19 | To contribute any of these modules, you'll need to: 20 | 21 | 1. A schema designed for that portion of the rest API as a new `.graphql` file 22 | 2. Add the new `.graphql` file to the `supergraph.yaml` 23 | 3. Add the connector config to the `router.yaml` and be sure to use the subgraph name you populated in the previous step (referenced in `supergraph.yaml`) -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/common-room/json-responses/members_email_.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "fullName": "Michael Watson", 4 | "activities_count": 3334, 5 | "avatar": "https://avatars.githubusercontent.com/u/8645958?u=2d97981f1bbdf44e76a47e67fdaa3d26354ddb74&v=4", 6 | "bio": "Developer Advocate for Apollo Federation - Previous Solutions Architect - 5+ yrs", 7 | "organization": "Apollo GraphQL", 8 | "organization_domain": "http://www.apollographql.com", 9 | "title": "Head of DevRel", 10 | "first_seen": "2018-10-03T14:37:25.000Z", 11 | "last_active": "2025-02-14T22:23:57.000Z", 12 | "location": { 13 | "raw": "San Francisco, California, United States", 14 | "city": "San Francisco", 15 | "region": "California", 16 | "country": "United States" 17 | }, 18 | "member_tags": [ 19 | { 20 | "id": 731426, 21 | "name": "team_member" 22 | }, 23 | { 24 | "id": 731431, 25 | "name": "contributor" 26 | } 27 | ], 28 | "segments": [ 29 | { 30 | "id": 123456, 31 | "name": "Segment Name" 32 | } 33 | ], 34 | "email": [ 35 | { 36 | "email": "watson+connectors+live@apollographql.com", 37 | "sources": [ 38 | "ConnectorsLiveUsers" 39 | ] 40 | } 41 | ], 42 | "url": [], 43 | "twitter": [], 44 | "github": [ 45 | "michael-watson" 46 | ], 47 | "linkedin": [ 48 | "in/michael-watson-85844442" 49 | ], 50 | "discord": [], 51 | "youtube": [], 52 | "common_room_member_url": "https://app.commonroom.io/community/1337/member/1337", 53 | "custom_fields": [ 54 | { 55 | "name": "Custom Field Name", 56 | "type": "string", 57 | "value": "" 58 | } 59 | ] 60 | } 61 | ] -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/common-room/router.yaml: -------------------------------------------------------------------------------- 1 | supergraph: 2 | listen: 127.0.0.1:4000 3 | 4 | headers: 5 | all: 6 | request: 7 | - propagate: 8 | matching: .* 9 | telemetry: 10 | instrumentation: 11 | spans: 12 | mode: spec_compliant 13 | 14 | connectors: 15 | subgraphs: 16 | contacts: 17 | $config: 18 | apiKey: ${env.COMMON_ROOM_API_KEY} -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/common-room/supergraph.yaml: -------------------------------------------------------------------------------- 1 | federation_version: =2.11.0 2 | subgraphs: 3 | contacts: 4 | routing_url: http://contacts 5 | schema: 6 | file: contacts.graphql 7 | -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/googlemaps/router.yaml: -------------------------------------------------------------------------------- 1 | supergraph: 2 | listen: 0.0.0.0:${env.PORT:-4000} 3 | 4 | headers: 5 | all: 6 | request: 7 | - propagate: 8 | matching: .* 9 | telemetry: 10 | instrumentation: 11 | spans: 12 | mode: spec_compliant 13 | 14 | connectors: 15 | sources: 16 | places.places: 17 | $config: 18 | GOOGLE_MAPS_API_KEY: ${env.GOOGLE_MAPS_API_KEY} -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/googlemaps/supergraph.yaml: -------------------------------------------------------------------------------- 1 | subgraphs: 2 | # places-legacy: 3 | # routing_url: http://places 4 | # schema: 5 | # file: places-legacy.graphql 6 | places: 7 | routing_url: http://places 8 | schema: 9 | file: places.graphql 10 | distance: 11 | routing_url: http://distancematrix 12 | schema: 13 | file: distancematrix.graphql 14 | timezone: 15 | routing_url: http://timezone 16 | schema: 17 | file: timezone.graphql 18 | federation_version: =2.11.0 -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/googlemaps/timezone.graphql: -------------------------------------------------------------------------------- 1 | extend schema 2 | @link( 3 | url: "https://specs.apollo.dev/federation/v2.11" 4 | import: ["@key", "@shareable", "@external", "@requires"] 5 | ) # Enable this schema to use Apollo Federation features 6 | @link( # Enable this schema to use Apollo Connectors 7 | url: "https://specs.apollo.dev/connect/v0.2" 8 | import: ["@connect", "@source"] 9 | ) 10 | 11 | #this connector uses the legacy timezone API. To enable this in Google, you must create an API key and give permissions to this API 12 | 13 | @source( 14 | name: "timezone" 15 | http: { baseURL: "https://maps.googleapis.com/maps/api/timezone/" } 16 | ) 17 | 18 | type Query { 19 | # Optional fallback query 20 | timezoneByCoords(lat: Float!, lng: Float!, timestamp: Int!): TimezoneInfo 21 | @connect( 22 | source: "timezone" 23 | http: { 24 | GET: "json?location={$args.lat},{$args.lng}×tamp={$args.timestamp}&key=YOUR_API_KEY" 25 | } 26 | selection: """ 27 | timeZoneId 28 | timeZoneName 29 | rawOffset 30 | dstOffset 31 | """ 32 | ) 33 | } 34 | 35 | type TimezoneInfo { 36 | timeZoneId: String 37 | timeZoneName: String 38 | rawOffset: Int 39 | dstOffset: Int 40 | } 41 | 42 | type Place @key(fields: "id", resolvable: false) { 43 | id: String @external 44 | location: Location @external 45 | timezone(timestamp: Int!): TimezoneInfo 46 | @requires(fields: "location { latitude longitude }") 47 | @connect( 48 | source: "timezone" 49 | http: { 50 | GET: "json?location={$this.location.latitude},{$this.location.longitude}×tamp={$args.timestamp}&key=YOUR_API_KEY" 51 | } 52 | selection: """ 53 | timeZoneId 54 | timeZoneName 55 | rawOffset 56 | dstOffset 57 | """ 58 | ) 59 | } 60 | 61 | type Location { 62 | latitude: Float @external 63 | longitude: Float @external 64 | } 65 | -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/heygen/avatars.graphql: -------------------------------------------------------------------------------- 1 | # These are the necessary federation and connector directives you will be using 2 | extend schema 3 | @link(url: "https://specs.apollo.dev/federation/v2.10") 4 | @link( 5 | url: "https://specs.apollo.dev/connect/v0.2" 6 | import: ["@connect", "@source"] 7 | ) 8 | # A @source directive defines a shared data source for multiple connectors. 9 | 10 | @source( 11 | name: "heygen-v2" 12 | http: { 13 | baseURL: "https://api.heygen.com/v2" 14 | headers: [{ name: "X-API-KEY", value: "{$config.apiKey}" }] 15 | } 16 | ) 17 | 18 | scalar Timestamp 19 | 20 | enum GroupType { 21 | PUBLIC_PHOTO 22 | PRIVATE 23 | } 24 | 25 | enum TrainStatus { 26 | empty 27 | } 28 | 29 | type Avatar { 30 | id: ID! 31 | name: String 32 | gender: String 33 | previewImageUrl: String 34 | previewVideoUrl: String 35 | } 36 | 37 | type AvatarGroup { 38 | id: ID! 39 | name: String! 40 | createdAt: Timestamp 41 | numLooks: Int 42 | previewImageUrl: String 43 | groupType: GroupType 44 | trainStatus: TrainStatus 45 | } 46 | 47 | type Query { 48 | listAvatars: [Avatar!]! 49 | @connect( 50 | source: "heygen-v2" 51 | http: { GET: "/avatars" } 52 | selection: """ 53 | $.data.avatars { 54 | id: avatar_id 55 | name: avatar_name 56 | gender 57 | previewImageUrl: preview_image_url 58 | previewVideoUrl: preview_video_url 59 | } 60 | """ 61 | ) 62 | 63 | listAvatarGroups(includePublic: Boolean = false): [AvatarGroup!]! 64 | @connect( 65 | source: "heygen-v2" 66 | http: { GET: "/avatar_group.list?include_public={$args.includePublic}" } 67 | selection: """ 68 | $.data.avatar_group_list { 69 | id 70 | name 71 | createdAt: created_at 72 | numLooks: num_looks 73 | previewImageUrl: preview_image_url 74 | groupType: group_type 75 | trainStatus: train_status 76 | } 77 | """ 78 | ) 79 | } 80 | -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/heygen/router.yaml: -------------------------------------------------------------------------------- 1 | supergraph: 2 | listen: 0.0.0.0:${env.PORT:-4000} 3 | 4 | headers: 5 | all: 6 | request: 7 | - propagate: 8 | matching: .* 9 | telemetry: 10 | instrumentation: 11 | spans: 12 | mode: spec_compliant 13 | 14 | connectors: 15 | subgraphs: 16 | heygen-avatars: 17 | $config: 18 | apiKey: ${env.HEYGEN_API_KEY} 19 | heygen-photo-avatars: 20 | $config: 21 | apiKey: ${env.HEYGEN_API_KEY} 22 | -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/heygen/supergraph.yaml: -------------------------------------------------------------------------------- 1 | federation_version: =2.11.0 2 | subgraphs: 3 | heygen-avatars: 4 | routing_url: http://heygen-avatars 5 | schema: 6 | file: avatars.graphql 7 | heygen-photo-avatars: 8 | routing_url: http://heygen-photo-avatars 9 | schema: 10 | file: photo-avatars.graphql 11 | -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/jira/README: -------------------------------------------------------------------------------- 1 | # Jira REST Connector 2 | 3 | This connector currently covers the Project and Issues objects in the Jira REST API v2. To use this, you'll need to add a `API_KEY` in your environment variables then running `rover` or the `router` with the config files in this folder. 4 | 5 | ## Additional Setup for VS Code Task runner 6 | 7 | Edit your `.vscode/settings.json` to include the Strapi specific keys 8 | 9 | ``` 10 | { 11 | "terminal.integrated.profiles.osx": { 12 | "graphos": { 13 | "path": "zsh", 14 | "args": ["-l"], 15 | "env": { 16 | "API_KEY": "", 17 | "APOLLO_KEY": "", 18 | ... 19 | } 20 | } 21 | }, 22 | "terminal.integrated.defaultProfile.osx": "graphos" 23 | } 24 | 25 | ``` 26 | 27 | Then you can execute the "Tasks: Run Task" command in VS code to execute the `rover dev` task or simply open a new terminal window in vscode with the `graphos` profile, then you can simply run `rover dev --supergraph-config supergraph.yaml --router-config router.yaml`. 28 | 29 | ## Contributing 30 | 31 | The following schema modules need to be: 32 | 33 | 1. A schema designed for that portion of the rest API as a new `.graphql` file 34 | 2. Additions to the `router.yaml` and `supergraph.yaml` files 35 | 36 | There are multiple moduels that can be implemented in the [documentation navigation](https://developer.atlassian.com/cloud/jira/platform/rest/v2/intro) panel. You can use the current connector as an example to follow and implement additional resources. -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/jira/router.yaml: -------------------------------------------------------------------------------- 1 | supergraph: 2 | listen: 0.0.0.0:${env.PORT:-4000} 3 | 4 | headers: 5 | all: 6 | request: 7 | - propagate: 8 | matching: .* 9 | telemetry: 10 | instrumentation: 11 | spans: 12 | mode: spec_compliant 13 | 14 | connectors: 15 | subgraphs: 16 | connector: 17 | $config: 18 | apiKey: ${env.API_KEY} -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/jira/supergraph.yaml: -------------------------------------------------------------------------------- 1 | federation_version: =2.11.0 2 | subgraphs: 3 | connector: 4 | routing_url: http://connector 5 | schema: 6 | file: connector.graphql 7 | -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/museums/README.md: -------------------------------------------------------------------------------- 1 | # Public Art Museum REST Connector 2 | 3 | This connector currently contains subgraphs schemas for: 4 | 5 | [The Art Institute of Chicago API](https://api.artic.edu/docs/#introduction) 6 | [The Metropolitan Museum of Art](https://metmuseum.github.io/?ref=public_apis&utm_medium=website) 7 | 8 | These Apis are public and free to use, see the respective documentaiton for more information about usage and limitations. 9 | 10 | These subgraph files are complimentary but do not depend on each other, they can be used independently. 11 | 12 | ## Additional Setup for VS Code Task runner 13 | 14 | Edit your `.vscode/settings.json` to include the following keys: 15 | 16 | ``` 17 | { 18 | "terminal.integrated.profiles.osx": { 19 | "graphos": { 20 | "path": "zsh", 21 | "args": ["-l"], 22 | "env": { 23 | "APOLLO_KEY": "", 24 | ... 25 | } 26 | } 27 | }, 28 | "terminal.integrated.defaultProfile.osx": "graphos" 29 | } 30 | ``` 31 | 32 | Once you've set this up, you can execute the `Tasks: Run Task` command in VS Code to run the `rover dev` task. 33 | Alternatively, you can open a new terminal window in VS Code with the `graphos` profile, then run `rover dev --supergraph-config supergraph.yaml`. 34 | 35 | ## Contributing 36 | 37 | Other Art Museums with public apis are good candidates to contribute to this schema. 38 | 39 | 1. Add a schema designed for the module as a new `.graphql` file. 40 | 2. Update the `supergraph.yaml` file accordingly. 41 | -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/museums/supergraph.yaml: -------------------------------------------------------------------------------- 1 | subgraphs: 2 | aic: 3 | routing_url: http://aic 4 | schema: 5 | file: chicagoArt.graphql 6 | met: 7 | routing_url: http://met 8 | schema: 9 | file: metMuseum.graphql 10 | federation_version: =2.11.0 -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/nws/README.md: -------------------------------------------------------------------------------- 1 | # NWS COnnector 2 | 3 | This connector implements NWS APIs. 4 | 5 | ## Prerequisites 6 | 7 | NWS maintains free to access APIs that enforce their own rate limits. 8 | [NWS API Documentation](https://api.weather.gov/) 9 | 10 | It is required to have a user-agent header with the best practice of adding contact information in the case of a security event. [See more information here](https://www.weather.gov/documentation/services-web-api) 11 | 12 | ## Getting Started 13 | 14 | 1. Create an [Apollo Studio](https://studio.apollographql.com/) account. This will provide the abilty to create and manage your graph including necesary credentials APOLLO_KEY and APOLLO_GRAPH_REF 15 | 2. [Install](https://www.apollographql.com/docs/rover/getting-started#installation-methods) and [authenticate](https://www.apollographql.com/docs/rover/configuring) Rover CLI to configure your graph and run locally. 16 | 3. Run `rover init` to generate a new connector. See the [Rover CLI documentation](https://www.apollographql.com/docs/rover) for more information and commands. 17 | 18 | 19 | ## Additional Setup for VS Code Task runner 20 | 21 | Edit your `.vscode/settings.json` to include the following keys: 22 | 23 | ``` 24 | { 25 | "terminal.integrated.profiles.osx": { 26 | "graphos": { 27 | "path": "zsh", 28 | "args": ["-l"], 29 | "env": { 30 | "API_KEY": "", 31 | "APOLLO_KEY": "", 32 | ... 33 | } 34 | } 35 | }, 36 | "terminal.integrated.defaultProfile.osx": "graphos" 37 | } 38 | ``` 39 | 40 | Once you've set this up, you can execute the `Tasks: Run Task` command in VS Code to run the `rover dev` task. 41 | Alternatively, you can open a new terminal window in VS Code with the `graphos` profile, then run `rover dev --supergraph-config supergraph.yaml --router-config router.yaml`. 42 | 43 | ## Contributing 44 | 45 | If you are interested in contributing to this or other connectors we welcome contributions. PLease see the [contributing guide](https://github.com/apollographql/connectors-community?tab=readme-ov-file#contributing-a-connector-to-the-community) for more information 46 | -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/nws/supergraph.yaml: -------------------------------------------------------------------------------- 1 | subgraphs: 2 | alerts: 3 | routing_url: http://localhost:4000 4 | schema: 5 | file: alerts.graphql 6 | federation_version: =2.11.0 7 | -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/odata/README: -------------------------------------------------------------------------------- 1 | # OData REST Connector 2 | 3 | This connector currently covers the People object in the [OData Basic Tutorial](https://www.odata.org/getting-started/basic-tutorial/) API. To use this, you'll need to add a `API_KEY` in your environment variables then running `rover` or the `router` with the config files in this folder. 4 | 5 | ## Contributing 6 | 7 | The following schema modules need to be: 8 | 9 | 1. A schema designed for that portion of the rest API as a new `.graphql` file 10 | 2. Additions to the `router.yaml` and `supergraph.yaml` files 11 | 12 | Modules: 13 | 14 | - [Photos (Entity)](https://services.odata.org/V4/TripPinServiceRW) 15 | - [Airlines (Entity)](https://services.odata.org/V4/TripPinServiceRW) 16 | - [Airports (Entity)](https://services.odata.org/V4/TripPinServiceRW) 17 | - [Me (Singleton)](https://services.odata.org/V4/TripPinServiceRW) 18 | - GetNearestAirport (FunctionImport) - http://services.odata.org/V4/TripPinService/GetNearestAirport(lat=33, lon=-118)) -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/odata/router.yaml: -------------------------------------------------------------------------------- 1 | supergraph: 2 | listen: 0.0.0.0:${env.PORT:-4000} 3 | 4 | headers: 5 | all: 6 | request: 7 | - propagate: 8 | matching: .* 9 | telemetry: 10 | instrumentation: 11 | spans: 12 | mode: spec_compliant 13 | 14 | # connectors: 15 | # subgraphs: 16 | # connector: 17 | # $config: 18 | # api: ${env.API_KEY} -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/odata/supergraph.yaml: -------------------------------------------------------------------------------- 1 | federation_version: =2.11.0 2 | subgraphs: 3 | connector: 4 | routing_url: http://connector 5 | schema: 6 | file: connector.graphql 7 | -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/openai/models.graphql: -------------------------------------------------------------------------------- 1 | extend schema 2 | @link(url: "https://specs.apollo.dev/federation/v2.10", import: ["@key", "@requires"]) 3 | @link( 4 | url: "https://specs.apollo.dev/connect/v0.2" 5 | import: ["@source", "@connect"] 6 | ) 7 | @source( 8 | name: "openai" 9 | http: { 10 | baseURL: "https://api.openai.com/v1/", 11 | headers:[{name:"Authorization", value:"Bearer {$config.apiKey}"}] 12 | } 13 | ) 14 | 15 | type Model { 16 | id: ID! 17 | created: Float 18 | ownedBy: String 19 | } 20 | 21 | type Query { 22 | models: [Model] 23 | @connect( 24 | source: "openai" 25 | http: { GET: "/models" } 26 | selection: """ 27 | $.data { 28 | id 29 | created 30 | ownedBy: owned_by 31 | } 32 | """ 33 | ) 34 | model(id:ID!): Model 35 | @connect( 36 | source: "openai" 37 | http: { GET: "/models/{$args.id}" } 38 | selection: """ 39 | $.data { 40 | id 41 | created 42 | ownedBy: owned_by 43 | } 44 | """ 45 | entity: true 46 | ) 47 | } -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/openai/router.yaml: -------------------------------------------------------------------------------- 1 | supergraph: 2 | listen: 0.0.0.0:${env.PORT:-4000} 3 | 4 | headers: 5 | all: 6 | request: 7 | - propagate: 8 | matching: .* 9 | telemetry: 10 | instrumentation: 11 | spans: 12 | mode: spec_compliant 13 | 14 | connectors: 15 | sources: 16 | assistants.openai: 17 | $config: 18 | apiKey: ${env.API_KEY} 19 | models.openai: 20 | $config: 21 | apiKey: ${env.API_KEY} 22 | chat.openai: 23 | $config: 24 | apiKey: ${env.API_KEY} -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/openai/supergraph.yaml: -------------------------------------------------------------------------------- 1 | federation_version: =2.11.0 2 | subgraphs: 3 | assistants: 4 | routing_url: http://assistants 5 | schema: 6 | file: assistants.graphql 7 | models: 8 | routing_url: http://models 9 | schema: 10 | file: models.graphql 11 | chat: 12 | routing_url: http://chat 13 | schema: 14 | file: chat-completions.graphql -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/pokeapi/README: -------------------------------------------------------------------------------- 1 | # Pokeapi REST Connector 2 | 3 | This connector currently covers the Pokemon, locations, moves and games in the [PokeAPI](https://pokeapi.co/). 4 | 5 | ## Additional Setup for VS Code Task runner 6 | 7 | Edit your `.vscode/settings.json` to include the following keys: 8 | 9 | ``` 10 | { 11 | "terminal.integrated.profiles.osx": { 12 | "graphos": { 13 | "path": "zsh", 14 | "args": ["-l"], 15 | "env": { 16 | "API_KEY": "", 17 | "APOLLO_KEY": "", 18 | ... 19 | } 20 | } 21 | }, 22 | "terminal.integrated.defaultProfile.osx": "graphos" 23 | } 24 | ``` 25 | 26 | Once you've set this up, you can execute the `Tasks: Run Task` command in VS Code to run the `rover dev` task. 27 | Alternatively, you can open a new terminal window in VS Code with the `graphos` profile, then run `rover dev --supergraph-config supergraph.yaml --router-config router.yaml`. 28 | 29 | ## Contributing 30 | 31 | 32 | The following schema modules can be added to this connector: 33 | 34 | - Abilities - https://pokeapi.co/docs/v2#abilities 35 | - Characteristics - https://pokeapi.co/docs/v2#characteristics 36 | - Egg Groups - https://pokeapi.co/docs/v2#egg_groups 37 | - Genders - https://pokeapi.co/docs/v2#genders 38 | - Growth Rates - https://pokeapi.co/docs/v2#growth_rates 39 | - Natures - https://pokeapi.co/docs/v2#natures 40 | - Pokeathlon Stats - https://pokeapi.co/docs/v2#pokeathlon 41 | 42 | To contribute them, make sure to: 43 | 44 | 1. Add a schema designed for the module as a new `.graphql` file. 45 | 2. Update the `supergraph.yaml` file accordingly. 46 | -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/pokeapi/games.graphql: -------------------------------------------------------------------------------- 1 | extend schema 2 | @link( 3 | url: "https://specs.apollo.dev/federation/v2.11" 4 | import: ["@key", "@requires"] 5 | ) 6 | @link( 7 | url: "https://specs.apollo.dev/connect/v0.2" 8 | import: ["@source", "@connect"] 9 | ) 10 | @source(name: "pokeapi", http: { baseURL: "https://pokeapi.co/api/v2/" }) 11 | 12 | type Generation @key(fields:"name"){ 13 | name: String 14 | moves: [Move] 15 | } 16 | 17 | type Move @key(fields: "name", resolvable: false) { 18 | name: String 19 | } 20 | type Version @key(fields: "name") { 21 | name: String 22 | versionGroup: VersionGroup 23 | } 24 | type VersionGroup @key(fields: "name") { 25 | name: String 26 | order: Int 27 | regions: [LocationArea] 28 | } 29 | type LocationArea @key(fields: "name",resolvable: false) { 30 | name: String 31 | } 32 | type Query { 33 | generation(name: String!): Generation 34 | @connect( 35 | source: "pokeapi" 36 | http: { GET: "generation/{$args.name}" } 37 | selection: """ 38 | name 39 | moves { 40 | name 41 | } 42 | """ 43 | entity: true 44 | ) 45 | version(name: String!): Version 46 | @connect( 47 | source: "pokeapi" 48 | http: { GET: "version/{$args.name}" } 49 | selection: """ 50 | name 51 | versionGroup: version_group { 52 | name 53 | } 54 | """ 55 | entity: true 56 | ) 57 | versionGroup(name: String!): VersionGroup 58 | @connect( 59 | source: "pokeapi" 60 | http: { GET: "version-group/{$args.name}" } 61 | selection: """ 62 | name 63 | order 64 | regions { 65 | name 66 | } 67 | """ 68 | entity: true 69 | ) 70 | } 71 | -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/pokeapi/router.yaml: -------------------------------------------------------------------------------- 1 | supergraph: 2 | listen: 0.0.0.0:${env.PORT:-4000} 3 | 4 | headers: 5 | all: 6 | request: 7 | - propagate: 8 | matching: .* 9 | telemetry: 10 | instrumentation: 11 | spans: 12 | mode: spec_compliant 13 | 14 | # connectors: 15 | # subgraphs: 16 | # connector: 17 | # $config: 18 | # apiKey: ${env.API_KEY} -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/pokeapi/supergraph.yaml: -------------------------------------------------------------------------------- 1 | federation_version: =2.11.0 2 | subgraphs: 3 | games: 4 | routing_url: http://games 5 | schema: 6 | file: games.graphql 7 | locations: 8 | routing_url: http://locations 9 | schema: 10 | file: locations.graphql 11 | moves: 12 | routing_url: http://moves 13 | schema: 14 | file: moves.graphql 15 | pokemon: 16 | routing_url: http://pokemon 17 | schema: 18 | file: pokemon.graphql 19 | -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/strapi/router.yaml: -------------------------------------------------------------------------------- 1 | supergraph: 2 | listen: 0.0.0.0:${env.PORT:-4000} 3 | 4 | headers: 5 | all: 6 | request: 7 | - propagate: 8 | matching: .* 9 | connectors: 10 | subgraphs: 11 | strapi-users: 12 | $config: 13 | apiKey: ${env.STRAPI_API_KEY} 14 | telemetry: 15 | instrumentation: 16 | spans: 17 | mode: spec_compliant 18 | override_subgraph_url: 19 | strapi-users: ${env.STRAPI_URL:-http://localhost:1337/api} -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/strapi/supergraph.yaml: -------------------------------------------------------------------------------- 1 | federation_version: =2.11.0 2 | subgraphs: 3 | strapi-users: 4 | routing_url: http://apiusers 5 | schema: 6 | file: users.graphql 7 | -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/stripe/router.yaml: -------------------------------------------------------------------------------- 1 | supergraph: 2 | listen: 0.0.0.0:${env.PORT:-4000} 3 | 4 | headers: 5 | all: 6 | request: 7 | - propagate: 8 | matching: .* 9 | connectors: 10 | subgraphs: 11 | stripe-checkout: 12 | $config: 13 | apiKey: ${env.STRIPE_API_KEY} 14 | stripe-core-resources: 15 | $config: 16 | apiKey: ${env.STRIPE_API_KEY} 17 | stripe-payment-methods: 18 | $config: 19 | apiKey: ${env.STRIPE_API_KEY} 20 | stripe-product: 21 | $config: 22 | apiKey: ${env.STRIPE_API_KEY} 23 | telemetry: 24 | instrumentation: 25 | spans: 26 | mode: spec_compliant -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/stripe/supergraph.yaml: -------------------------------------------------------------------------------- 1 | federation_version: =2.11.0 2 | subgraphs: 3 | stripe-checkout: 4 | routing_url: http://stripe-checkout 5 | schema: 6 | file: checkout.graphql 7 | stripe-core-resources: 8 | routing_url: http://stripe-core-resources 9 | schema: 10 | file: core-resources.graphql 11 | stripe-payment-methods: 12 | routing_url: http://stripe-payment-methods 13 | schema: 14 | file: payment-methods.graphql 15 | stripe-product: 16 | routing_url: http://stripe-products 17 | schema: 18 | file: products.graphql 19 | -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/supabase/router.yaml: -------------------------------------------------------------------------------- 1 | connectors: 2 | sources: 3 | speakerSubmission.supabase: 4 | $config: 5 | anonKey: ${env.anonKey} -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/supabase/supergraph.yaml: -------------------------------------------------------------------------------- 1 | subgraphs: 2 | supabase: 3 | routing_url: http://localhost:4000 4 | schema: 5 | file: supabase.graphql 6 | federation_version: =2.11.0 -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/thespacedevs/README: -------------------------------------------------------------------------------- 1 | # The Space Devs Launch Library REST Connector 2 | 3 | This connector currently covers [The Space Devs Launch Library REST API](https://ll.thespacedevs.com/). 4 | 5 | ## Prerequisites 6 | 7 | The Space Devs is a free to access API that enforces their own rate limits; all the API data is available at no cost for up to 15 requests per hour. 8 | 9 | ## Additional Setup for VS Code Task runner 10 | 11 | Edit your `.vscode/settings.json` to include the following keys: 12 | 13 | ``` 14 | { 15 | "terminal.integrated.profiles.osx": { 16 | "graphos": { 17 | "path": "zsh", 18 | "args": ["-l"], 19 | "env": { 20 | "API_KEY": "", 21 | "APOLLO_KEY": "", 22 | ... 23 | } 24 | } 25 | }, 26 | "terminal.integrated.defaultProfile.osx": "graphos" 27 | } 28 | ``` 29 | 30 | Once you've set this up, you can execute the `Tasks: Run Task` command in VS Code to run the `rover dev` task. 31 | Alternatively, you can open a new terminal window in VS Code with the `graphos` profile, then run `rover dev --supergraph-config supergraph.yaml --router-config router.yaml`. 32 | 33 | ## Contributing 34 | 35 | 36 | The following schema modules can be added to this connector: 37 | 38 | - Example 1 39 | - Example 2 40 | 41 | To contribute them, make sure to: 42 | 43 | 1. Add a schema designed for the module as a new `.graphql` file. 44 | 2. Update the `router.yaml` and `supergraph.yaml` files accordingly. 45 | 46 | See [REST API reference]() for other modules that can be implemented. You can use the current modules in this folder as examples to work with. -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/thespacedevs/api-throttle.graphql: -------------------------------------------------------------------------------- 1 | extend schema 2 | @link( 3 | url: "https://specs.apollo.dev/federation/v2.10" 4 | import: ["@key", "@requires", "@shareable"] 5 | ) 6 | @link( 7 | url: "https://specs.apollo.dev/connect/v0.2" 8 | import: ["@source", "@connect"] 9 | ) 10 | @source(name: "llv2", http: { baseURL: "https://ll.thespacedevs.com/2.3.0/" }) 11 | 12 | type ApiThrottle{ 13 | yourRequestLimit: Int 14 | limitFrequencySecs: Int 15 | currentUse: Int 16 | nextUseSecs: Int 17 | ident: String 18 | } 19 | 20 | type Query { 21 | apiThrottle: ApiThrottle 22 | @connect( 23 | source: "llv2" 24 | http: { GET: "/api-throttle/?format=json" } 25 | selection: """ 26 | yourRequestLimit: your_request_limit 27 | limitFrequencySecs: limit_frequency_secs 28 | currentUse: current_use 29 | nextUseSecs: next_use_secs 30 | ident 31 | """ 32 | ) 33 | } -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/thespacedevs/supergraph.yaml: -------------------------------------------------------------------------------- 1 | federation_version: =2.11.0 2 | subgraphs: 3 | agencies: 4 | routing_url: http://agencies 5 | schema: 6 | file: agencies.graphql 7 | api-throttle: 8 | routing_url: http://api-throttle 9 | schema: 10 | file: api-throttle.graphql 11 | astronauts: 12 | routing_url: http://astronauts 13 | schema: 14 | file: astronauts.graphql 15 | celestial-bodies: 16 | routing_url: http://celestial-bodies 17 | schema: 18 | file: celestial-bodies.graphql 19 | docking-events: 20 | routing_url: http://docking-events 21 | schema: 22 | file: docking-events.graphql 23 | launches: 24 | routing_url: http://launches 25 | schema: 26 | file: launches.graphql 27 | 28 | # 6 down 29 | # 12 more to go 30 | # expeditions: 31 | # routing_url: http://launches 32 | # schema: 33 | # file: launches.graphql 34 | # landings: 35 | # routing_url: http://launches 36 | # schema: 37 | # file: launches.graphql 38 | # launcher_configurations: 39 | # routing_url: http://launches 40 | # schema: 41 | # file: launches.graphql 42 | # launchers: 43 | # routing_url: http://launches 44 | # schema: 45 | # file: launches.graphql 46 | # locations: 47 | # routing_url: http://launches 48 | # schema: 49 | # file: launches.graphql 50 | # mission_patches: 51 | # routing_url: http://launches 52 | # schema: 53 | # file: launches.graphql 54 | # pads: 55 | # routing_url: http://launches 56 | # schema: 57 | # file: launches.graphql 58 | # payloads: 59 | # routing_url: http://launches 60 | # schema: 61 | # file: launches.graphql 62 | # programs: 63 | # routing_url: http://launches 64 | # schema: 65 | # file: launches.graphql 66 | # space_stations: 67 | # routing_url: http://launches 68 | # schema: 69 | # file: launches.graphql 70 | # spacecraft: 71 | # routing_url: http://launches 72 | # schema: 73 | # file: launches.graphql 74 | # spacewalks: 75 | # routing_url: http://launches 76 | # schema: 77 | # file: launches.graphql -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/tint/README: -------------------------------------------------------------------------------- 1 | # Tint REST Connector 2 | 3 | This connector currently covers the Accounts and Social Feeds object in the [Tint REST API](https://developers.tintup.com/v2/). To use this, you'll need to add a `API_KEY` in your environment variables then running `rover` or the `router` with the config files in this folder. 4 | 5 | ## Additional Setup for VS Code Task runner 6 | 7 | Edit your `.vscode/settings.json` to include the Strapi specific keys 8 | 9 | ``` 10 | { 11 | "terminal.integrated.profiles.osx": { 12 | "graphos": { 13 | "path": "zsh", 14 | "args": ["-l"], 15 | "env": { 16 | "API_KEY": "", 17 | "APOLLO_KEY": "", 18 | ... 19 | } 20 | } 21 | }, 22 | "terminal.integrated.defaultProfile.osx": "graphos" 23 | } 24 | ``` 25 | 26 | Then you can execute the "Tasks: Run Task" command in VS code to execute the `rover dev` task or simply open a new terminal window in vscode with the `graphos` profile, then you can simply run `rover dev --supergraph-config supergraph.yaml --router-config router.yaml`. 27 | 28 | ## Contributing 29 | 30 | The following schema modules need to include: 31 | 32 | 1. A schema designed for that portion of the rest API as a new `.graphql` file 33 | 2. Additions to the `router.yaml` and `supergraph.yaml` files 34 | 35 | See [developer documentation](https://developers.tintup.com/v2/) navigation panel for other modules that can be implemented. You can use the current modules in this folder as examples to work with. -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/tint/accounts.graphql: -------------------------------------------------------------------------------- 1 | 2 | extend schema 3 | @link(url: "https://specs.apollo.dev/federation/v2.10", import: ["@key", "@requires"]) 4 | @link( 5 | url: "https://specs.apollo.dev/connect/v0.2" 6 | import: ["@source", "@connect"] 7 | ) 8 | @source( 9 | name: "tint" 10 | http: { 11 | # https://developers.tintup.com/v2/ 12 | baseURL: "https://api.tintup.dev/v2/", 13 | headers: [ 14 | { name: "Authorization", value: "Bearer {$config.apiKey}"} 15 | ] 16 | } 17 | ) 18 | 19 | type Account { 20 | id: ID! 21 | externalId: ID! 22 | type: String 23 | status: String 24 | name: String 25 | username: String 26 | image: String 27 | } 28 | 29 | type Query { 30 | account(id:ID!): Account 31 | # https://developers.tintup.com/v2/#tag/accounts/paths/~1v2~1teams~1%7Bteam_id%7D~1accounts~1%7Baccount_id%7D/get 32 | @connect( 33 | source: "tint" 34 | http: { GET: "/teams/TeamID/accounts/{$args.id}" } 35 | entity: true 36 | selection: """ 37 | $.data { 38 | id 39 | $.attributes { 40 | externalId: external_id 41 | type 42 | status 43 | name 44 | username 45 | image: image_url 46 | } 47 | } 48 | """ 49 | ) 50 | accounts: [Account] 51 | # https://developers.tintup.com/v2/#tag/accounts/paths/~1v2~1teams~1%7Bteam_id%7D~1accounts/get 52 | @connect( 53 | source: "tint" 54 | http: { GET: "/teams/TeamID/accounts" } 55 | selection: """ 56 | $.data { 57 | id 58 | $.attributes { 59 | externalId: external_id 60 | type 61 | status 62 | name 63 | username 64 | image: image_url 65 | } 66 | } 67 | """ 68 | ) 69 | } -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/tint/router.yaml: -------------------------------------------------------------------------------- 1 | supergraph: 2 | listen: 0.0.0.0:${env.PORT:-4000} 3 | 4 | headers: 5 | all: 6 | request: 7 | - propagate: 8 | matching: .* 9 | telemetry: 10 | instrumentation: 11 | spans: 12 | mode: spec_compliant 13 | 14 | connectors: 15 | subgraphs: 16 | tint-accounts: 17 | $config: 18 | apiKey: ${env.API_KEY} 19 | tint-social-feeds: 20 | $config: 21 | apiKey: ${env.API_KEY} -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/tint/social-feeds.graphql: -------------------------------------------------------------------------------- 1 | extend schema 2 | @link(url: "https://specs.apollo.dev/federation/v2.10", import: ["@key", "@requires"]) 3 | @link( 4 | url: "https://specs.apollo.dev/connect/v0.2" 5 | import: ["@source", "@connect"] 6 | ) 7 | @source( 8 | name: "tint" 9 | http: { 10 | # https://developers.tintup.com/v2/ 11 | baseURL: "https://api.tintup.dev/v2/", 12 | headers: [ 13 | { name: "Authorization", value: "Bearer {$config.apiKey}"} 14 | ] 15 | } 16 | ) 17 | 18 | type SocialFeed { 19 | id: ID! 20 | type: String 21 | status: String 22 | name: String 23 | source: String 24 | } 25 | 26 | type Query { 27 | socialFeed(id:ID!): SocialFeed 28 | # https://developers.tintup.com/v2/#tag/social_feeds/paths/~1v2~1teams~1%7Bteam_id%7D~1social_feeds~1%7Bsocial_feed_id%7D/get 29 | @connect( 30 | source: "tint" 31 | http: { GET: "/teams/TeamID/social_feeds/{$args.id}" } 32 | entity: true 33 | selection: """ 34 | $.data { 35 | id 36 | $.attributes { 37 | type 38 | status 39 | name 40 | source 41 | } 42 | } 43 | """ 44 | ) 45 | socialFeeds: [SocialFeed] 46 | # https://developers.tintup.com/v2/#tag/social_feeds/paths/~1v2~1teams~1%7Bteam_id%7D~1social_feeds/get 47 | @connect( 48 | source: "tint" 49 | http: { GET: "/teams/TeamID/social_feeds" } 50 | selection: """ 51 | $.data { 52 | id 53 | $.attributes { 54 | type 55 | status 56 | name 57 | source 58 | } 59 | } 60 | """ 61 | ) 62 | } -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/tint/supergraph.yaml: -------------------------------------------------------------------------------- 1 | federation_version: =2.11.0 2 | subgraphs: 3 | tint-accounts: 4 | routing_url: http://accounts 5 | schema: 6 | file: accounts.graphql 7 | tint-social-feeds: 8 | routing_url: http://tint-social-feeds 9 | schema: 10 | file: social-feeds.graphql 11 | -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/todoist/README.md: -------------------------------------------------------------------------------- 1 | # Todoist Connector 2 | 3 | This connector implements Todoist APIs and currently covers Projects and Tasks. 4 | 5 | ## Prerequisites 6 | 7 | Todoist provides access to API's and the product in a freemium model. See their documentation for more information. 8 | [Todoist v1 API Documentation](https://developer.todoist.com/api/v1) 9 | 10 | *Please note that while todoist does have a v2 API, v1 is the latest version as of the time of development. 11 | The structure of the JSON response for tasks and Projects is different between these two versions. 12 | 13 | A Bearer token is required to call todoist APIs, see [the documentation](https://www.todoist.com/help/articles/find-your-api-token-Jpzx9IIlB) for more information. 14 | 15 | ## Getting Started 16 | 17 | 1. Create an [Apollo Studio](https://studio.apollographql.com/) account. This will provide the abilty to create and manage your graph including necesary credentials APOLLO_KEY and APOLLO_GRAPH_REF 18 | 2. [Install](https://www.apollographql.com/docs/rover/getting-started#installation-methods) and [authenticate](https://www.apollographql.com/docs/rover/configuring) Rover CLI to configure your graph and run locally. 19 | 3. Run `rover init` to generate a new connector. See the [Rover CLI documentation](https://www.apollographql.com/docs/rover) for more information and commands. 20 | 21 | 22 | ## Additional Setup for VS Code Task runner 23 | 24 | Edit your `.vscode/settings.json` to include the following keys: 25 | 26 | ``` 27 | { 28 | "terminal.integrated.profiles.osx": { 29 | "graphos": { 30 | "path": "zsh", 31 | "args": ["-l"], 32 | "env": { 33 | "API_KEY": "", 34 | "APOLLO_KEY": "", 35 | ... 36 | } 37 | } 38 | }, 39 | "terminal.integrated.defaultProfile.osx": "graphos" 40 | } 41 | ``` 42 | 43 | Once you've set this up, you can execute the `Tasks: Run Task` command in VS Code to run the `rover dev` task. 44 | Alternatively, you can open a new terminal window in VS Code with the `graphos` profile, then run `rover dev --supergraph-config supergraph.yaml --router-config router.yaml`. 45 | 46 | ## Contributing 47 | 48 | If you are interested in contributing to this or other connectors we welcome contributions. PLease see the [contributing guide](https://github.com/apollographql/connectors-community?tab=readme-ov-file#contributing-a-connector-to-the-community) for more information 49 | -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/todoist/supergraph.yaml: -------------------------------------------------------------------------------- 1 | subgraphs: 2 | todoist: 3 | routing_url: http://localhost:4000 4 | schema: 5 | file: todoist.graphql 6 | federation_version: =2.11.0 -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/trimblemaps/connector.graphql: -------------------------------------------------------------------------------- 1 | extend schema 2 | @link( 3 | url: "https://specs.apollo.dev/federation/v2.10" 4 | import: ["@key", "@requires"] 5 | ) 6 | @link( 7 | url: "https://specs.apollo.dev/connect/v0.2" 8 | import: ["@source", "@connect"] 9 | ) 10 | @source( 11 | name: "trimblemaps" 12 | http: { 13 | baseURL: "https://singlesearch.alk.com/" 14 | headers: [{ name: "Authorization", value: "{$config.api}" }] 15 | } 16 | ) 17 | 18 | type Address { 19 | shortFormatted: String 20 | timezone: String! 21 | } 22 | 23 | type Geo { 24 | lat: String! 25 | long: String! 26 | } 27 | 28 | type Query { 29 | """ 30 | PC*Miler Web Services - Single Search - https://developer.trimblemaps.com/restful-apis/location/single-search/single-search-api/ 31 | """ 32 | addressByGeo(lat: String!, long: String!): Address 33 | @connect( 34 | source: "trimblemaps" 35 | http: { 36 | GET: "ww/api/search" 37 | queryParams: """ 38 | query: $([$args.lat, $args.long])->joinNotNull(",") 39 | matchNamedRoadsOnly: $('true') 40 | maxCleanupMiles: $('0.2') 41 | """ 42 | } 43 | selection: """ 44 | # https://developer.trimblemaps.com/restful-apis/location/single-search/single-search-api/#kbd-classkbd-get-roundedgetkbd-search 45 | shortFormatted:Locations->first.ShortString 46 | timezone:Locations->first.TimeZone 47 | """ 48 | ) 49 | locationByAddress(address: String!, city: String!, state: String!): Geo 50 | @connect( 51 | source: "trimblemaps" 52 | http: { 53 | GET: "na/api/search" 54 | queryParams: """ 55 | query: $([$args.address, $args.city])->joinNotNull(",") 56 | states: $args.state 57 | countries: $('US') 58 | """ 59 | } 60 | selection: """ 61 | # https://developer.trimblemaps.com/restful-apis/location/single-search/single-search-api/#kbd-classkbd-get-roundedgetkbd-search 62 | lat:Locations->first.Coords.Lat 63 | long:Locations->first.Coords.Lon 64 | """ 65 | ) 66 | } 67 | -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/trimblemaps/router.yaml: -------------------------------------------------------------------------------- 1 | supergraph: 2 | listen: 127.0.0.1:4000 3 | 4 | headers: 5 | all: 6 | request: 7 | - propagate: 8 | matching: .* 9 | telemetry: 10 | instrumentation: 11 | spans: 12 | mode: spec_compliant 13 | 14 | connectors: 15 | subgraphs: 16 | connector: 17 | $config: 18 | api: ${env.API_KEY} -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/trimblemaps/supergraph.yaml: -------------------------------------------------------------------------------- 1 | federation_version: =2.11.0 2 | subgraphs: 3 | connector: 4 | routing_url: http://connector 5 | schema: 6 | file: connector.graphql 7 | -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/twilio/README.md: -------------------------------------------------------------------------------- 1 | # Twilio REST API Connector 2 | 3 | This connector implements implements Twilio SMS APis and current covers sending and querying messages. 4 | 5 | ## Prerequisites 6 | 7 | To use this connector you must have a Twilio account and verified phone number. See [Twilio documentation](https://www.twilio.com/docs/messaging/api/message-resource) for more information 8 | 9 | A Base64 encoded Bearer token is required. Generate this value and store it in your env. 10 | 11 | ## Getting Started 12 | 13 | 1. Create an [Apollo Studio](https://studio.apollographql.com/) account. This will provide the abilty to create and manage your graph including necesary credentials APOLLO_KEY and APOLLO_GRAPH_REF 14 | 2. [Install](https://www.apollographql.com/docs/rover/getting-started#installation-methods) and [authenticate](https://www.apollographql.com/docs/rover/configuring) Rover CLI to configure your graph and run locally. 15 | 3. Run `rover init` to generate a new connector. See the [Rover CLI documentation](https://www.apollographql.com/docs/rover) for more information and commands. 16 | 17 | 18 | ## Additional Setup for VS Code Task runner 19 | 20 | Edit your `.vscode/settings.json` to include the following keys: 21 | 22 | ``` 23 | { 24 | "terminal.integrated.profiles.osx": { 25 | "graphos": { 26 | "path": "zsh", 27 | "args": ["-l"], 28 | "env": { 29 | "API_KEY": "", 30 | "APOLLO_KEY": "", 31 | ... 32 | } 33 | } 34 | }, 35 | "terminal.integrated.defaultProfile.osx": "graphos" 36 | } 37 | ``` 38 | 39 | Once you've set this up, you can execute the `Tasks: Run Task` command in VS Code to run the `rover dev` task. 40 | Alternatively, you can open a new terminal window in VS Code with the `graphos` profile, then run `rover dev --supergraph-config supergraph.yaml --router-config router.yaml`. 41 | 42 | ## Contributing 43 | 44 | If you are interested in contributing to this or other connectors we welcome contributions. PLease see the [contributing guide](https://github.com/apollographql/connectors-community?tab=readme-ov-file#contributing-a-connector-to-the-community) for more information 45 | -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/twilio/router.yaml: -------------------------------------------------------------------------------- 1 | #this value should be a Base64 encoded string comprised of your twilioAcctID:authToken 2 | connectors: 3 | subgraphs: 4 | messages: 5 | $config: 6 | apiKey: ${env.twilioKey} -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/twilio/supergraph.yaml: -------------------------------------------------------------------------------- 1 | subgraphs: 2 | twilio: 3 | routing_url: http://localhost:4000 4 | schema: 5 | file: messages.graphql 6 | federation_version: =2.11.0 -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/usgs/earthquakes-nominatum/README.md: -------------------------------------------------------------------------------- 1 | # USGS earthquakes with location data from Nominatum REST Connector 2 | 3 | This connector is a minimal implementation of USGS Earthquakes and Nominatum reverse geocoding API developed to support a tutorial demo in //blog link coming soon// and is implemented in [graphql-version branch](https://github.com/AmandaApollo/earthquake-finder/tree/graphql-version) of [this repository](https://github.com/AmandaApollo/earthquake-finder). 4 | 5 | ## Prerequisites 6 | 7 | USGS and Nominatum are free to access APIs that enforce their own rate limits. 8 | [USGS API Documentation](https://earthquake.usgs.gov/fdsnws/event/1/) 9 | [Nominatum API Documentation](https://nominatim.org/release-docs/develop/api/Overview/) 10 | 11 | ## Getting Started 12 | 13 | 1. Create an [Apollo Studio](https://studio.apollographql.com/) account. This will provide the abilty to create and manage your graph including necesary credentials APOLLO_KEY and APOLLO_GRAPH_REF 14 | 2. [Install](https://www.apollographql.com/docs/rover/getting-started#installation-methods) and [authenticate](https://www.apollographql.com/docs/rover/configuring) Rover CLI to configure your graph and run locally. 15 | 3. Run `rover init` to generate a new connector. See the [Rover CLI documentation](https://www.apollographql.com/docs/rover) for more information and commands. 16 | 17 | 18 | ## Additional Setup for VS Code Task runner 19 | 20 | Edit your `.vscode/settings.json` to include the following keys: 21 | 22 | ``` 23 | { 24 | "terminal.integrated.profiles.osx": { 25 | "graphos": { 26 | "path": "zsh", 27 | "args": ["-l"], 28 | "env": { 29 | "API_KEY": "", 30 | "APOLLO_KEY": "", 31 | ... 32 | } 33 | } 34 | }, 35 | "terminal.integrated.defaultProfile.osx": "graphos" 36 | } 37 | ``` 38 | 39 | Once you've set this up, you can execute the `Tasks: Run Task` command in VS Code to run the `rover dev` task. 40 | Alternatively, you can open a new terminal window in VS Code with the `graphos` profile, then run `rover dev --supergraph-config supergraph.yaml --router-config router.yaml`. 41 | 42 | ## Contributing 43 | 44 | This implementation was created to support a tutorial and therefore will not accept modifications to evolve it at this time. If you are interested in contributing to this resource, you may do so as a separate .`graphql` file. 45 | -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/usgs/earthquakes-nominatum/earthquake-simple.graphql: -------------------------------------------------------------------------------- 1 | extend schema 2 | @link(url: "https://specs.apollo.dev/federation/v2.10", import: ["@key"]) # Enable this schema to use Apollo Federation features 3 | @link( # Enable this schema to use Apollo Connectors 4 | url: "https://specs.apollo.dev/connect/v0.2" 5 | import: ["@connect", "@source"] 6 | ) 7 | @source( 8 | name: "usgs" 9 | http: { baseURL: "https://earthquake.usgs.gov/fdsnws/event/1/" } 10 | ) 11 | 12 | @source( 13 | name: "location" 14 | http: { 15 | baseURL: "https://nominatim.openstreetmap.org/" 16 | headers: [{ name: "User-Agent", value: "testing" }] 17 | } 18 | ) 19 | 20 | type EarthquakeProperties { 21 | mag: Float 22 | place: String 23 | time: Float 24 | updated: Float 25 | url: String 26 | title: String 27 | } 28 | 29 | type EarthquakeGeometry { 30 | #this returns 3 values - lon,lat,depth in km 31 | coordinates: [Float] 32 | } 33 | 34 | type Earthquake { 35 | id: ID! 36 | properties: EarthquakeProperties 37 | geometry: EarthquakeGeometry 38 | display_name: String 39 | @connect( 40 | source: "location" 41 | http: { 42 | GET: "reverse" 43 | queryParams: """ 44 | lat: $this.geometry.coordinates->slice(1,2)->first 45 | lon: $this.geometry.coordinates->first 46 | format: $('json') 47 | """ 48 | } 49 | selection: """ 50 | $.display_name 51 | """ 52 | ) 53 | } 54 | 55 | type Query { 56 | recentEarthquakes(limit: Int = 5 lat: String! lon: String! maxRadius: Int = 100): [Earthquake] 57 | @connect( 58 | source: "usgs" 59 | http: { 60 | GET: "query?format=geojson" 61 | queryParams: """ 62 | latitude: $args.lat 63 | longitude: $args.lon 64 | maxradiuskm: $args.maxRadius 65 | limit: $args.limit 66 | """ 67 | } 68 | selection: """ 69 | $.features 70 | { 71 | properties{ 72 | mag 73 | place 74 | time 75 | updated 76 | url 77 | title 78 | } 79 | geometry{ 80 | coordinates 81 | } 82 | id 83 | } 84 | 85 | """ 86 | ) 87 | } -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/usgs/earthquakes-nominatum/router.yaml: -------------------------------------------------------------------------------- 1 | # only for use in development 2 | cors: 3 | allow_any_origin: true -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/usgs/earthquakes-nominatum/supergraph.yaml: -------------------------------------------------------------------------------- 1 | subgraphs: 2 | earthquake-simple: 3 | routing_url: http://localhost:4000 4 | schema: 5 | file: earthquake-simple.graphql 6 | federation_version: =2.11.0 7 | -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/usgs/earthquakes/README.md: -------------------------------------------------------------------------------- 1 | # USGS earthquakes with location data from Nominatum REST Connector 2 | 3 | This connector is a minimal implementation of USGS Earthquakes and Nominatum reverse geocoding API developed to support a tutorial demo in //blog link coming soon// and is implemented in [graphql-version branch](https://github.com/AmandaApollo/earthquake-finder/tree/graphql-version) of [this repository](https://github.com/AmandaApollo/earthquake-finder). 4 | 5 | ## Prerequisites 6 | 7 | USGS and Nominatum are free to access APIs that enforce their own rate limits. 8 | [USGS API Documentation](https://earthquake.usgs.gov/fdsnws/event/1/) 9 | [Nominatum API Documentation](https://nominatim.org/release-docs/develop/api/Overview/) 10 | 11 | ## Getting Started 12 | 13 | 1. Create an [Apollo Studio](https://studio.apollographql.com/) account. This will provide the abilty to create and manage your graph including necesary credentials APOLLO_KEY and APOLLO_GRAPH_REF 14 | 2. [Install](https://www.apollographql.com/docs/rover/getting-started#installation-methods) and [authenticate](https://www.apollographql.com/docs/rover/configuring) Rover CLI to configure your graph and run locally. 15 | 3. Run `rover init` to generate a new connector. See the [Rover CLI documentation](https://www.apollographql.com/docs/rover) for more information and commands. 16 | 17 | 18 | ## Additional Setup for VS Code Task runner 19 | 20 | Edit your `.vscode/settings.json` to include the following keys: 21 | 22 | ``` 23 | { 24 | "terminal.integrated.profiles.osx": { 25 | "graphos": { 26 | "path": "zsh", 27 | "args": ["-l"], 28 | "env": { 29 | "API_KEY": "", 30 | "APOLLO_KEY": "", 31 | ... 32 | } 33 | } 34 | }, 35 | "terminal.integrated.defaultProfile.osx": "graphos" 36 | } 37 | ``` 38 | 39 | Once you've set this up, you can execute the `Tasks: Run Task` command in VS Code to run the `rover dev` task. 40 | Alternatively, you can open a new terminal window in VS Code with the `graphos` profile, then run `rover dev --supergraph-config supergraph.yaml --router-config router.yaml`. 41 | 42 | ## Contributing 43 | 44 | This implementation was created to support a tutorial and therefore will not accept modifications to evolve it at this time. If you are interested in contributing to this resource, you may do so as a separate .`graphql` file. 45 | -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/usgs/earthquakes/supergraph.yaml: -------------------------------------------------------------------------------- 1 | subgraphs: 2 | earthquakes: 3 | routing_url: http://localhost:4000 4 | schema: 5 | file: earthquakes.graphql 6 | federation_version: =2.11.0 7 | -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/usps/README: -------------------------------------------------------------------------------- 1 | # USPS REST Connector 2 | 3 | This connector currently covers the [Tracking object](https://developer.usps.com/trackingv3) in the [USPS REST API](https://developer.usps.com/). To use this, you'll need to add a `API_KEY` in your environment variables then running `rover` or the `router` with the config files in this folder. 4 | 5 | ## Additional Setup for VS Code Task runner 6 | 7 | Edit your `.vscode/settings.json` to include the Strapi specific keys 8 | 9 | ``` 10 | { 11 | "terminal.integrated.profiles.osx": { 12 | "graphos": { 13 | "path": "zsh", 14 | "args": ["-l"], 15 | "env": { 16 | "API_KEY": "", 17 | "APOLLO_KEY": "", 18 | ... 19 | } 20 | } 21 | }, 22 | "terminal.integrated.defaultProfile.osx": "graphos" 23 | } 24 | 25 | ``` 26 | 27 | Then you can execute the "Tasks: Run Task" command in VS code to execute the `rover dev` task or simply open a new terminal window in vscode with the `graphos` profile, then you can simply run `rover dev --supergraph-config supergraph.yaml --router-config router.yaml`. 28 | 29 | ## Contributing 30 | 31 | The following schema modules need to include: 32 | 33 | 1. A schema designed for that portion of the rest API as a new `.graphql` file 34 | 2. Additions to the `router.yaml` and `supergraph.yaml` files 35 | 36 | You can view the [USPS API Catalog](https://developer.usps.com/apis) for other modules to implement. -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/usps/router.yaml: -------------------------------------------------------------------------------- 1 | supergraph: 2 | listen: 0.0.0.0:${env.PORT:-4000} 3 | 4 | headers: 5 | all: 6 | request: 7 | - propagate: 8 | matching: .* 9 | telemetry: 10 | instrumentation: 11 | spans: 12 | mode: spec_compliant 13 | 14 | connectors: 15 | subgraphs: 16 | tracking: 17 | $config: 18 | apiKey: ${env.API_KEY} -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/usps/supergraph.yaml: -------------------------------------------------------------------------------- 1 | federation_version: =2.11.0 2 | subgraphs: 3 | tracking: 4 | routing_url: http://tracking 5 | schema: 6 | file: tracking.graphql 7 | -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/zendesk/README: -------------------------------------------------------------------------------- 1 | # Zendesk REST Connector 2 | 3 | This connector currently covers the Orders and LineItem objects in the [Zendesk Sales CRM REST API](https://developer.zendesk.com/api-reference/sales-crm). To use this, you'll need to add a `API_KEY` in your environment variables then running `rover` or the `router` with the config files in this folder. 4 | 5 | ## Additional Setup for VS Code Task runner 6 | 7 | Edit your `.vscode/settings.json` to include the Strapi specific keys 8 | 9 | ``` 10 | { 11 | "terminal.integrated.profiles.osx": { 12 | "graphos": { 13 | "path": "zsh", 14 | "args": ["-l"], 15 | "env": { 16 | "API_KEY": "", 17 | "APOLLO_KEY": "", 18 | ... 19 | } 20 | } 21 | }, 22 | "terminal.integrated.defaultProfile.osx": "graphos" 23 | } 24 | 25 | ``` 26 | 27 | Then you can execute the "Tasks: Run Task" command in VS code to execute the `rover dev` task or simply open a new terminal window in vscode with the `graphos` profile, then you can simply run `rover dev --supergraph-config supergraph.yaml --router-config router.yaml`. 28 | 29 | ## Contributing 30 | 31 | The following schema modules need to include: 32 | 33 | 1. A schema designed for that portion of the rest API as a new `.graphql` file 34 | 2. Additions to the `router.yaml` and `supergraph.yaml` files 35 | 36 | See [developer documentation](https://developer.zendesk.com/api-reference/sales-crm) navigation panel for other modules that can be implemented. You can use the current modules in this folder as examples to work with. -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/zendesk/router.yaml: -------------------------------------------------------------------------------- 1 | supergraph: 2 | listen: 0.0.0.0:${env.PORT:-4000} 3 | 4 | headers: 5 | all: 6 | request: 7 | - propagate: 8 | matching: .* 9 | telemetry: 10 | instrumentation: 11 | spans: 12 | mode: spec_compliant 13 | 14 | connectors: 15 | subgraphs: 16 | connector: 17 | $config: 18 | apiKey: ${env.API_KEY} -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/connectors/zendesk/supergraph.yaml: -------------------------------------------------------------------------------- 1 | federation_version: =2.11.0 2 | subgraphs: 3 | connector: 4 | routing_url: http://connector 5 | schema: 6 | file: connector.graphql 7 | -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "connectors-community", 3 | "version": "1.0.0", 4 | "description": "A simple repository designed share connectors in the community and ensure they follow a specific standard.", 5 | "type": "module", 6 | "main": "file-new/index.js", 7 | "author": "Apollo GraphQL", 8 | "license": "MIT", 9 | "scripts": { 10 | "start": "node file-new/index.js" 11 | }, 12 | "dependencies": { 13 | "@faker-js/faker": "^9.0.3", 14 | "dotenv": "^16.4.5", 15 | "graphql": "^16.9.0", 16 | "graphql-request": "^7.1.0", 17 | "js-yaml": "^4.1.0", 18 | "prompts": "^2.4.2" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /sampleWorkspace/connectors-community/supergraph.yaml: -------------------------------------------------------------------------------- 1 | federation_version: =2.11.0 2 | subgraphs: 3 | connector: 4 | routing_url: http://connector 5 | schema: 6 | file: connector.graphql 7 | -------------------------------------------------------------------------------- /sampleWorkspace/httpSchema/apollo.config.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | client: { 3 | service: { 4 | name: "httpSchema", 5 | url: "http://localhost:7096/graphql", 6 | // url: "https://localhost:7097/graphql", 7 | // skipSSLValidation: true, 8 | }, 9 | }, 10 | }; 11 | -------------------------------------------------------------------------------- /sampleWorkspace/httpSchema/self-signed.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDkzCCAnugAwIBAgIUVNlDGdat5znvwWhOEFQLq7BWzNwwDQYJKoZIhvcNAQEL 3 | BQAwWTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM 4 | GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDESMBAGA1UEAwwJbG9jYWxob3N0MB4X 5 | DTI0MDkwMjA4MTgwNloXDTM0MDgzMTA4MTgwNlowWTELMAkGA1UEBhMCQVUxEzAR 6 | BgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5 7 | IEx0ZDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A 8 | MIIBCgKCAQEAvHLw9Ey0WoRLxjVIajxVAT4za1pUQw3E9mtl57DPHDcdGWR56S9w 9 | KPjmND5lrtALZ5K+EKqslJdPf6Uxzxpf6phVnwpFwq5hPeY/Gpm77HxpPiJ61Q9r 10 | fsYnLtGXiZta0kbdrisALB+3QykEHOerDUF3wGiVYVcpDu7WF/WcLaF+zUlgf1gQ 11 | RTa5B3HpdCk34LiKPm9IZpWRpgLC90ro+HP+nBo7FoLYwu+WiPxg49qWEUY8fk+d 12 | TuJVdH7lf8GxcfM2oCzhBGpT5O/t6lqYBkgZvvY3YAERmAxg/OSeuUa6ChOMLK2T 13 | +2MRLy7eLaaeTmPMFjjrzFODCA2/ekfGVwIDAQABo1MwUTAdBgNVHQ4EFgQUpEu/ 14 | mbpTwcOGdPZ8NhTl1e16G84wHwYDVR0jBBgwFoAUpEu/mbpTwcOGdPZ8NhTl1e16 15 | G84wDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAhfSAl9VFS+Fk 16 | Wkmsl1ndoXvLWVDy36YepbNfXUeB+iwebIgdyZhNu6VdpcHsPNBuUV4wr4mgZ7PK 17 | Ksp3kKdqTDTAfBzHNBiOK7QgGyrDQJa0/Nn8ifmS+TYYCOs4FnkOXCUFipXCCMaS 18 | KzFYc9Ls4jtAxiSN58NmwxW9fqRHqwHW4o2Z/aNx4EnCEat0x4QcAqq/qfEodmjH 19 | jI7/AKb4UE+yEcJnZSlUDdpM4zPM3FcjmY7JVyfd/CziywR7rHGbLz7XQcCkYyDv 20 | 5xqz0Lvk0ZtOC73cFWS41qfh8lrt34CNPoG7EaPFf+tMwhvjNooDHMQCb8y1A0Y3 21 | 2yaDZNbCbQ== 22 | -----END CERTIFICATE----- 23 | -------------------------------------------------------------------------------- /sampleWorkspace/httpSchema/self-signed.key: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC8cvD0TLRahEvG 3 | NUhqPFUBPjNrWlRDDcT2a2XnsM8cNx0ZZHnpL3Ao+OY0PmWu0Atnkr4QqqyUl09/ 4 | pTHPGl/qmFWfCkXCrmE95j8ambvsfGk+InrVD2t+xicu0ZeJm1rSRt2uKwAsH7dD 5 | KQQc56sNQXfAaJVhVykO7tYX9ZwtoX7NSWB/WBBFNrkHcel0KTfguIo+b0hmlZGm 6 | AsL3Suj4c/6cGjsWgtjC75aI/GDj2pYRRjx+T51O4lV0fuV/wbFx8zagLOEEalPk 7 | 7+3qWpgGSBm+9jdgARGYDGD85J65RroKE4wsrZP7YxEvLt4tpp5OY8wWOOvMU4MI 8 | Db96R8ZXAgMBAAECggEAGRrrnHLZi2jY2sDUyF5dlAr6zlWcKHYITtceSNWmXyO9 9 | Ky8BChPen9QPgFdDCZ0VX94jQaooeqqGa0K71ijf2ADPq0ky46LX4+dYHHhC762K 10 | rGiV2kDceROh5bFYvFAniHWWE8gOalJsAjT6eMqo4DJgEeXSPMO1UxQguSlofdrX 11 | 9PIkRmsmQVmVh17V4RJhhW/qg8r75OwpM1uFTknikaXwd9Rw5/HZhW4hXP5EeM2x 12 | rcaYtXudhUyG/AWCrRPpHdGGNpHPmpwKUw3uADYAb2Hicjswx34kmWAbcwVJMs8d 13 | 3QR/4hyrJnVSgYAB8/5oiNsnvaF/sO6/9KkDFpF03QKBgQDxrVJznfA0xgeVTGxt 14 | sLRhbsUyVn5tHteEdbvbTGLfl80Dayzlht9rTrjYXgQUevw40+chQW8LPEA8gmyM 15 | oCyAMouk+DJ5rl75jQnQh1/pob+ReyFi7Jl4D6Ro8J6gP6nds+wZ/BN5WLNtd/KI 16 | BMwi4fEyKjT7nKTVFNQlrZEG6wKBgQDHng2nFYbSEKv1lb5HabSxJ1bbTHld0lzI 17 | tn5zEmZ9PW6jBM0UJMEmkPRAvzhGGnzbRM0hYhiZR1FBR9T6BCJb+1N0HfT0Xo2X 18 | MTOuz8auLRtH73SCRbRoxVbz+TFmLVQuwAXdwIT+p4AgEqoJ+QyMKwuwr70AGZmm 19 | SkL08Bp7RQKBgQDYZfOgJtmAx5jerFGiXkkFvSPBkQUfPDCKIMmW8WzO/KPL3dmT 20 | pBLFiPWmd3h7xiu1zrf0ZRzDGK4EAFymBn4SRDAaBUtc/S95kDoriCvvjK912qTo 21 | aSZ6BLeYZ2wB3T+CjqpoEfh1/WCcMnzuIi2PRnSsEHLkoTxOt5nGKwXjBQKBgDve 22 | o6mhQzZt2aVmrBMvGQqpCdvsK9p/5WQtl+9bbXHSowQxxHBuNaAjiZ6Bu5cLCreZ 23 | Aw0oJsiSI0S5Dp+N7eA4mOcStQ017rGSCDY+CxDiZnRE1WTdEyb5SQMTkkVbAwyi 24 | ex/vRfQ6uKrl7infkGvZ3T+49a65/uNpEnv0J30hAoGBAJwhlCGf3BhMPrXjXGsp 25 | qxtCAbnaARErq0cI/nP6EKv8U0zOte09j/KKqFhckzsN3Df+P7dSuciIbFEDFY8Y 26 | aWVRMDF/owMo7qrb/Hyvt72gRtRAeypN1Zf7Uy7JtP7PMqdvMynK0xSdrGAl4UCV 27 | 6AOSsKQotsgA2R1PKV89Rn2R 28 | -----END PRIVATE KEY----- 29 | -------------------------------------------------------------------------------- /sampleWorkspace/httpSchema/src/test.js: -------------------------------------------------------------------------------- 1 | import gql from "graphql-tag"; 2 | gql` 3 | query Test { 4 | books { 5 | title 6 | author 7 | } 8 | } 9 | `; 10 | -------------------------------------------------------------------------------- /sampleWorkspace/localSchema/apollo.config.ts: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | client: { 3 | service: { 4 | name: "localSchema", 5 | localSchemaFile: "./starwarsSchema.graphql", 6 | }, 7 | }, 8 | }; 9 | -------------------------------------------------------------------------------- /sampleWorkspace/localSchema/src/test.js: -------------------------------------------------------------------------------- 1 | import gql from "graphql-tag"; 2 | gql` 3 | query Test { 4 | droid(id: "2000") { 5 | name 6 | } 7 | } 8 | `; 9 | 10 | // prettier-ignore 11 | const verylonglala = gql`type Foo { baaaaaar: String }` 12 | -------------------------------------------------------------------------------- /sampleWorkspace/localSchema/starwarsSchema.graphql: -------------------------------------------------------------------------------- 1 | ../fixtures/starwarsSchema.graphql -------------------------------------------------------------------------------- /sampleWorkspace/localSchemaArray/apollo.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "client": { 3 | "service": { 4 | // test 5 | "name": "localMultiSchema", 6 | "localSchemaFile": ["./starwarsSchema.graphql", "./planets.graphql"] 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /sampleWorkspace/localSchemaArray/planets.graphql: -------------------------------------------------------------------------------- 1 | """ 2 | The query type, represents all of the entry points into our object graph 3 | """ 4 | type Query { 5 | planets: [Planet] 6 | } 7 | """ 8 | The planets mentioned in the Star Wars trilogy 9 | """ 10 | type Planet { 11 | """ 12 | Id of the planet 13 | """ 14 | id: ID! 15 | 16 | """ 17 | Name of the planet 18 | """ 19 | name: String! 20 | } 21 | -------------------------------------------------------------------------------- /sampleWorkspace/localSchemaArray/src/test.js: -------------------------------------------------------------------------------- 1 | import gql from "graphql-tag"; 2 | gql` 3 | query Test { 4 | droid(id: "2000") { 5 | dName: name 6 | } 7 | planets { 8 | id 9 | name 10 | } 11 | } 12 | `; 13 | -------------------------------------------------------------------------------- /sampleWorkspace/localSchemaArray/starwarsSchema.graphql: -------------------------------------------------------------------------------- 1 | ../fixtures/starwarsSchema.graphql -------------------------------------------------------------------------------- /sampleWorkspace/rover/apollo.config.yaml: -------------------------------------------------------------------------------- 1 | rover: 2 | profile: VSCode-E2E 3 | bin: ../../node_modules/@apollo/rover/binary/rover-0.27.0 4 | -------------------------------------------------------------------------------- /sampleWorkspace/rover/src/test.graphql: -------------------------------------------------------------------------------- 1 | extend schema 2 | @link( 3 | url: "https://specs.apollo.dev/federation/v2.8" 4 | import: ["@key", "@override", "@requires", "@external", "@shareable"] 5 | ) 6 | 7 | type Query { 8 | a: A 9 | } 10 | 11 | type A @key(fields: "a") { 12 | a: ID @override(from: "DNE") 13 | b: String! @requires(fields: "c") @shareable 14 | c: String! @external 15 | } 16 | -------------------------------------------------------------------------------- /sampleWorkspace/rover/src/test.js: -------------------------------------------------------------------------------- 1 | import gql from "graphql-tag"; 2 | 3 | sdfsdfs; 4 | gql` 5 | """ 6 | The query type, represents all of the entry points into our object graph 7 | """ 8 | type Query { 9 | me: User! 10 | } 11 | 12 | """ 13 | Test 14 | """ 15 | type User { 16 | id: ID! 17 | name: String! 18 | } 19 | `; 20 | 21 | console.log("foobar!"); 22 | 23 | gql` 24 | type User { 25 | lastName: String! 26 | } 27 | `; 28 | 29 | // prettier-ignore 30 | const verylonglala = gql`type Foo { baaaaaar: String }` 31 | -------------------------------------------------------------------------------- /sampleWorkspace/rover/supergraph.yaml: -------------------------------------------------------------------------------- 1 | subgraphs: 2 | subgraph: 3 | schema: 4 | file: src/test.graphql 5 | -------------------------------------------------------------------------------- /sampleWorkspace/sampleWorkspace.code-workspace: -------------------------------------------------------------------------------- 1 | { 2 | "folders": [ 3 | { 4 | "path": "localSchema" 5 | }, 6 | { 7 | "path": "clientSchema" 8 | }, 9 | { 10 | "path": "spotifyGraph" 11 | }, 12 | { 13 | "path": "httpSchema" 14 | }, 15 | { 16 | "path": "localSchemaArray" 17 | }, 18 | { 19 | "path": "rover" 20 | }, 21 | { 22 | "path": "configFileTypes" 23 | }, 24 | { 25 | "path": "../src/language-server/__tests__/fixtures/documents" 26 | }, 27 | { 28 | "path": "../src/__tests__/fixtures" 29 | }, 30 | { 31 | "path": "connectors-community/connectors" 32 | } 33 | ], 34 | "settings": { 35 | "apollographql.devTools.showPanel": "detect", 36 | "apollographql.devTools.serverPort": 7095, 37 | "editor.tokenColorCustomizations": { 38 | "textMateRules": [ 39 | { 40 | "scope": [ "meta.repository" ], 41 | "settings": { "fontStyle": "underline" } 42 | }, 43 | { 44 | "scope": ["meta.repository.Comment.identifier"], 45 | "settings": { 46 | "foreground": "#ffffff17", 47 | "fontStyle": "" 48 | } 49 | } 50 | ] 51 | }, 52 | }, 53 | } 54 | -------------------------------------------------------------------------------- /sampleWorkspace/spotifyGraph/apollo.config.mjs: -------------------------------------------------------------------------------- 1 | export default { 2 | client: { 3 | service: "spotify-demo-graph-519427f5@main", 4 | }, 5 | }; 6 | -------------------------------------------------------------------------------- /sampleWorkspace/spotifyGraph/src/test.js: -------------------------------------------------------------------------------- 1 | import gql from "graphql-tag"; 2 | gql` 3 | query CurrentUserQuery { 4 | me { 5 | profile { 6 | id 7 | displayName 8 | } 9 | } 10 | } 11 | `; 12 | -------------------------------------------------------------------------------- /src/__e2e__/run.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | const { runCLI } = require("@jest/core"); 3 | const yargs = require("yargs"); 4 | const { yargsOptions } = require("jest-cli"); 5 | 6 | async function run() { 7 | const root = path.join(__dirname, "..", ".."); 8 | const argv = await yargs(JSON.parse(process.env.TEST_ARGV || "[]").slice(2)) 9 | .alias("help", "h") 10 | .options(yargsOptions).argv; 11 | 12 | const results = await runCLI( 13 | { 14 | ...argv, 15 | config: path.join(root, "jest.e2e.config.js"), 16 | runInBand: true, 17 | }, 18 | [root], 19 | ); 20 | process.exit(results.results.numFailedTests); 21 | } 22 | 23 | module.exports.run = run; 24 | -------------------------------------------------------------------------------- /src/__e2e__/runTests.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | const path = require("path"); 3 | const { runTests } = require("@vscode/test-electron"); 4 | const { runMockServer } = require("./mockServer.js"); 5 | const { loadDefaultMocks } = require("./mocks.js"); 6 | 7 | async function main() { 8 | const disposables = /**{@type Disposable[]}*/ []; 9 | try { 10 | // The folder containing the Extension Manifest package.json 11 | // Passed to `--extensionDevelopmentPath` 12 | const extensionDevelopmentPath = path.resolve(__dirname, "../../"); 13 | // The path to the extension test runner script 14 | // Passed to --extensionTestsPath 15 | const extensionTestsPath = path.resolve(__dirname, "./run.js"); 16 | process.env.TEST_ARGV = JSON.stringify(process.argv); 17 | 18 | const TEST_PORT = 7096; 19 | process.env.APOLLO_ENGINE_ENDPOINT = "http://localhost:7096/apollo"; 20 | process.env.MOCK_SERVER_PORT = String(TEST_PORT); 21 | disposables.push( 22 | ...(await Promise.all([ 23 | runMockServer(TEST_PORT, false, loadDefaultMocks), 24 | runMockServer(TEST_PORT + 1, true, loadDefaultMocks), 25 | ])), 26 | ); 27 | // Download VS Code, unzip it and run the integration test 28 | const exitCode = await runTests({ 29 | extensionDevelopmentPath, 30 | extensionTestsPath, 31 | version: process.env.VSCODE_VERSION || "stable", 32 | launchArgs: [ 33 | "--disable-extensions", 34 | `${extensionDevelopmentPath}/sampleWorkspace/sampleWorkspace.code-workspace`, 35 | ], 36 | }); 37 | process.exit(exitCode); 38 | } catch (err) { 39 | console.error(err); 40 | console.error("Failed to run tests"); 41 | process.exit(1); 42 | } finally { 43 | disposables.forEach((d) => d[Symbol.dispose]()); 44 | } 45 | } 46 | 47 | main(); 48 | -------------------------------------------------------------------------------- /src/__e2e__/setup.js: -------------------------------------------------------------------------------- 1 | jest.setTimeout(10000); 2 | -------------------------------------------------------------------------------- /src/__e2e__/vscode-environment.js: -------------------------------------------------------------------------------- 1 | const { TestEnvironment } = require("jest-environment-node"); 2 | const vscode = require("vscode"); 3 | 4 | class VsCodeEnvironment extends TestEnvironment { 5 | async setup() { 6 | await super.setup(); 7 | this.global.vscode = vscode; 8 | } 9 | 10 | async teardown() { 11 | this.global.vscode = {}; 12 | await super.teardown(); 13 | } 14 | } 15 | 16 | module.exports = VsCodeEnvironment; 17 | -------------------------------------------------------------------------------- /src/__e2e__/vscode.js: -------------------------------------------------------------------------------- 1 | module.exports = global.vscode; 2 | -------------------------------------------------------------------------------- /src/__mocks__/fs.js: -------------------------------------------------------------------------------- 1 | const { fs } = require("memfs"); 2 | 3 | module.exports = fs; 4 | -------------------------------------------------------------------------------- /src/__tests__/statusBar.test.ts: -------------------------------------------------------------------------------- 1 | // import StatusBar from "../statusBar"; 2 | 3 | // TODO (jgzuke) disable this until we migrate away from `vscode`. 4 | // https://code.visualstudio.com/api/working-with-extensions/testing-extension#migrating-from-vscode 5 | describe.skip("statusBar", () => { 6 | it("only shows loaded state when it's supposed to", () => { 7 | // const statusBar = new StatusBar({ hasActiveTextEditor: true }); 8 | // expect(statusBar.statusBarItem.text).toEqual(StatusBar.loadingStateText); 9 | // statusBar.showLoadedState({ hasActiveTextEditor: true }); 10 | // expect(statusBar.statusBarItem.text).toEqual(StatusBar.loadedStateText); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /src/env/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./typescript-utility-types"; 2 | -------------------------------------------------------------------------------- /src/env/typescript-utility-types.ts: -------------------------------------------------------------------------------- 1 | export type WithRequired = T & Required>; 2 | export type DeepPartial = { [P in keyof T]?: DeepPartial }; 3 | -------------------------------------------------------------------------------- /src/language-server/__e2e__/configFileTypes.e2e.ts: -------------------------------------------------------------------------------- 1 | import { writeFile } from "fs/promises"; 2 | import { 3 | reloadService, 4 | waitForLSP, 5 | resolveRelativeToSampleWorkspace, 6 | } from "./utils"; 7 | 8 | test.each([ 9 | ["cjsConfig", "commonjs"], 10 | ["cjsConfig", "module"], 11 | ["mjsConfig", "module"], 12 | ["mjsConfig", "commonjs"], 13 | ["jsConfigWithCJS", "commonjs"], 14 | ["jsConfigWithCJS", "module"], 15 | ["jsConfigWithESM", "module"], 16 | ["jsConfigWithESM", "commonjs"], 17 | ["tsConfigWithCJS", "commonjs"], 18 | ["tsConfigWithCJS", "module"], 19 | ["tsConfigWithESM", "module"], 20 | ["tsConfigWithESM", "commonjs"], 21 | ] as const)("%s with `type: '%s'`", async (project, moduleType) => { 22 | await writeFile( 23 | resolveRelativeToSampleWorkspace(`configFileTypes/${project}/package.json`), 24 | `${JSON.stringify( 25 | { 26 | name: "test", 27 | type: moduleType, 28 | }, 29 | undefined, 30 | 2, 31 | )}\n`, 32 | "utf-8", 33 | ); 34 | await reloadService(); 35 | const stats = await waitForLSP(`configFileTypes/${project}/src/test.js`); 36 | expect(stats.serviceId).toBe(project); 37 | }); 38 | -------------------------------------------------------------------------------- /src/language-server/__e2e__/httpSchema.e2e.ts: -------------------------------------------------------------------------------- 1 | import { TextEditor } from "vscode"; 2 | import { 3 | closeAllEditors, 4 | openEditor, 5 | getCompletionItems, 6 | getHover, 7 | getPositionForEditor, 8 | GetPositionFn, 9 | } from "./utils"; 10 | 11 | let editor: TextEditor; 12 | let getPosition: GetPositionFn; 13 | beforeAll(async () => { 14 | closeAllEditors(); 15 | editor = await openEditor("httpSchema/src/test.js"); 16 | getPosition = getPositionForEditor(editor); 17 | }); 18 | 19 | test("completion", async () => { 20 | expect( 21 | (await getCompletionItems(editor, getPosition("bo|oks")))[0], 22 | ).toStrictEqual({ 23 | label: "books", 24 | detail: "[Book]", 25 | }); 26 | expect( 27 | (await getCompletionItems(editor, getPosition("au|thor")))[0], 28 | ).toStrictEqual({ 29 | label: "author", 30 | detail: "String", 31 | }); 32 | }); 33 | 34 | test("hover", async () => { 35 | expect(await getHover(editor, getPosition("au|thor"))).toMatchInlineSnapshot(` 36 | "\`\`\`graphql 37 | Book.author: String 38 | \`\`\`" 39 | `); 40 | }); 41 | -------------------------------------------------------------------------------- /src/language-server/__e2e__/localSchema.e2e.ts: -------------------------------------------------------------------------------- 1 | import { TextEditor } from "vscode"; 2 | import { 3 | closeAllEditors, 4 | openEditor, 5 | getCompletionItems, 6 | getHover, 7 | GetPositionFn, 8 | getPositionForEditor, 9 | } from "./utils"; 10 | 11 | let editor: TextEditor; 12 | let getPosition: GetPositionFn; 13 | beforeAll(async () => { 14 | closeAllEditors(); 15 | editor = await openEditor("localSchema/src/test.js"); 16 | getPosition = getPositionForEditor(editor); 17 | }); 18 | 19 | test("completion", async () => { 20 | expect( 21 | (await getCompletionItems(editor, getPosition("dro|id")))[0], 22 | ).toStrictEqual({ 23 | label: "droid", 24 | detail: "Droid", 25 | }); 26 | expect( 27 | (await getCompletionItems(editor, getPosition("na|me")))[0], 28 | ).toStrictEqual({ 29 | label: "name", 30 | detail: "String!", 31 | }); 32 | }); 33 | 34 | test("hover", async () => { 35 | expect(await getHover(editor, getPosition("na|me"))).toMatchInlineSnapshot(` 36 | "\`\`\`graphql 37 | Droid.name: String! 38 | \`\`\` 39 | 40 | --- 41 | 42 | What others call this droid" 43 | `); 44 | }); 45 | -------------------------------------------------------------------------------- /src/language-server/__e2e__/localSchemaArray.e2e.ts: -------------------------------------------------------------------------------- 1 | import { TextEditor } from "vscode"; 2 | import { 3 | closeAllEditors, 4 | openEditor, 5 | getCompletionItems, 6 | getHover, 7 | GetPositionFn, 8 | getPositionForEditor, 9 | } from "./utils"; 10 | 11 | let editor: TextEditor; 12 | let getPosition: GetPositionFn; 13 | beforeAll(async () => { 14 | closeAllEditors(); 15 | editor = await openEditor("localSchemaArray/src/test.js"); 16 | getPosition = getPositionForEditor(editor); 17 | }); 18 | 19 | test("completion", async () => { 20 | expect( 21 | (await getCompletionItems(editor, getPosition("dro|id")))[0], 22 | ).toStrictEqual({ 23 | label: "droid", 24 | detail: "Droid", 25 | }); 26 | expect( 27 | (await getCompletionItems(editor, getPosition("d|Name: name")))[0], 28 | ).toStrictEqual({ 29 | label: "name", 30 | detail: "String!", 31 | }); 32 | expect( 33 | (await getCompletionItems(editor, getPosition("pl|anet")))[0], 34 | ).toStrictEqual({ 35 | label: "planets", 36 | detail: "[Planet]", 37 | }); 38 | }); 39 | 40 | test("hover", async () => { 41 | expect(await getHover(editor, getPosition("d|Name: name"))) 42 | .toMatchInlineSnapshot(` 43 | "\`\`\`graphql 44 | Droid.name: String! 45 | \`\`\` 46 | 47 | --- 48 | 49 | What others call this droid" 50 | `); 51 | expect(await getHover(editor, getPosition("pl|anet"))).toMatchInlineSnapshot(` 52 | "\`\`\`graphql 53 | Query.planets: [Planet] 54 | \`\`\`" 55 | `); 56 | }); 57 | -------------------------------------------------------------------------------- /src/language-server/__tests__/fileSet.test.ts: -------------------------------------------------------------------------------- 1 | import { FileSet } from "../fileSet"; 2 | import { URI } from "vscode-uri"; 3 | 4 | describe("fileSet", () => { 5 | describe("includesFile", () => { 6 | it("matches includes starting with ./", () => { 7 | const fileSet = new FileSet({ 8 | excludes: [], 9 | includes: ["./src/**/*.tsx"], 10 | rootURI: URI.parse("/project"), 11 | }); 12 | const file = "file:///project/src/Component.tsx"; 13 | expect(fileSet.includesFile(file)).toBe(true); 14 | }); 15 | 16 | it("matches includes not starting with ./", () => { 17 | const fileSet = new FileSet({ 18 | excludes: [], 19 | includes: ["src/**/*.tsx"], 20 | rootURI: URI.parse("/project"), 21 | }); 22 | const file = "file:///project/src/Component.tsx"; 23 | expect(fileSet.includesFile(file)).toBe(true); 24 | }); 25 | 26 | it("does not match excludes starting with ./", () => { 27 | const fileSet = new FileSet({ 28 | excludes: ["./src/Component.tsx"], 29 | includes: ["./src/**/*.tsx"], 30 | rootURI: URI.parse("/project"), 31 | }); 32 | const file = "file:///project/src/Component.tsx"; 33 | expect(fileSet.includesFile(file)).toBe(false); 34 | }); 35 | 36 | it("does not match excludes not starting with ./", () => { 37 | const fileSet = new FileSet({ 38 | excludes: ["src/Component.tsx"], 39 | includes: ["src/**/*.tsx"], 40 | rootURI: URI.parse("/project"), 41 | }); 42 | const file = "file:///project/src/Component.tsx"; 43 | expect(fileSet.includesFile(file)).toBe(false); 44 | }); 45 | }); 46 | }); 47 | -------------------------------------------------------------------------------- /src/language-server/__tests__/fixtures/documents/commentWithTemplate.ts: -------------------------------------------------------------------------------- 1 | // hint for reading the snapshots generated by this file: 2 | // it is important to check that a rule doesn't only enter `meta.embedded.block.graphql` 3 | // but also leaves it again 4 | 5 | /* NormalComment */ `query Foo {test}`; 6 | 7 | // prettier-ignore 8 | { 9 | const _1 = /* GraphQL */`query Q1 {test}`; 10 | const _2 = 11 | /* GraphQL */` 12 | query Q2 { 13 | test 14 | } 15 | `; 16 | } 17 | 18 | /* GraphQL */ `query Q3 {test}`; 19 | /*GraphQL*/ `query Q4 {test}`; 20 | /** GraphQL */ `query Q5 {test}`; 21 | 22 | const _3 = /* GraphQL */ ` 23 | query Q6 { 24 | test 25 | } 26 | `; 27 | 28 | // syntax highlighting cannot work in all examples after this - textmate grammars don't work over multiple lines like this 29 | 30 | /** 31 | * GraphQL 32 | */ `query Q7 {test}`; 33 | 34 | /* GraphQL */ 35 | `query Q8 {test}`; 36 | 37 | /* graphql */ 38 | `query Q9 {test}`; 39 | 40 | /* gql */ 41 | `query Q10 {test}`; 42 | -------------------------------------------------------------------------------- /src/language-server/__tests__/fixtures/documents/functionCall.ts: -------------------------------------------------------------------------------- 1 | // hint for reading the snapshots generated by this file: 2 | // it is important to check that a rule doesn't only enter `meta.embedded.block.graphql` 3 | // but also leaves it again 4 | 5 | declare function gql(arg: string, ...args: any[]): void; 6 | declare function foo(...args: any[]): void; 7 | declare type SomeResult = any; 8 | declare type SomeVariables = any; 9 | 10 | // for comparison - this is what a normal function all is colored 11 | foo(`query Foo { test }`); 12 | 13 | // if possible, these should look the same 14 | foo("notATemplate"); 15 | gql("notATemplate"); 16 | foo<"">("notATemplate"); 17 | gql<"">("notATemplate"); 18 | 19 | // prettier-ignore 20 | gql(`query Q1($arg: String!) { test }`) 21 | 22 | // prettier-ignore 23 | gql(`query Q2 { test }`) 24 | 25 | // prettier-ignore 26 | gql ( `query Q3 { test }` ) 27 | 28 | gql(` 29 | query Q4 { 30 | test 31 | } 32 | `); 33 | 34 | // prettier-ignore 35 | gql ( ` 36 | query Q5 { 37 | test 38 | } 39 | ` ); 40 | 41 | // syntax highlighting cannot work in all examples after this - textmate grammars don't work over multiple lines like this 42 | 43 | gql< 44 | { 45 | test: string; 46 | }, 47 | { 48 | test: string; 49 | } 50 | >(` 51 | query Q6 { 52 | test 53 | } 54 | `); 55 | 56 | // prettier-ignore 57 | gql( 58 | ` 59 | query Q7 { 60 | test 61 | } 62 | ` 63 | ); 64 | 65 | gql( 66 | // ts-ignore 67 | ` 68 | query Q8 { 69 | test 70 | } 71 | `, 72 | `query {}`, 73 | ); 74 | 75 | // prettier-ignore 76 | gql<{ 77 | test: string; 78 | },{ 79 | test: string; 80 | }>(`query Q9 { test }`) 81 | 82 | // prettier-ignore 83 | gql( 84 | `query Q10 { test }` 85 | ) 86 | 87 | // prettier-ignore 88 | gql 89 | ( 90 | `query Q11 { test }` 91 | ) 92 | 93 | export {}; 94 | -------------------------------------------------------------------------------- /src/language-server/__tests__/fixtures/documents/taggedTemplate.ts: -------------------------------------------------------------------------------- 1 | // hint for reading the snapshots generated by this file: 2 | // it is important to check that a rule doesn't only enter `meta.embedded.block.graphql` 3 | // but also leaves it again 4 | 5 | declare function gql(strings: TemplateStringsArray): void; 6 | declare function foo(strings: TemplateStringsArray): void; 7 | declare type SomeResult = any; 8 | declare type SomeVariables = any; 9 | 10 | // for comparison - this is what a normal function all is colored 11 | foo`query Foo { test }`; 12 | foo`query Foo { test }`; 13 | 14 | // prettier-ignore 15 | gql`query Q1 { test }` 16 | 17 | // prettier-ignore 18 | gql`query Q2 { test }` 19 | 20 | // prettier-ignore 21 | gql ` 22 | query Q3 { test }` 23 | 24 | // prettier-ignore 25 | gql `query Q4 { test }` 26 | 27 | gql` 28 | query Q5 { 29 | test 30 | } 31 | `; 32 | 33 | gql` 34 | query Q6 { 35 | test 36 | } 37 | `; 38 | 39 | // prettier-ignore 40 | gql ` 41 | query Q7 { 42 | test 43 | } 44 | `; 45 | 46 | // syntax highlighting cannot work in all examples after this - textmate grammars don't work over multiple lines like this 47 | 48 | // prettier-ignore 49 | gql 50 | `query Q8 { test }` 51 | 52 | // prettier-ignore 53 | gql<{ 54 | test: string; 55 | },{ 56 | test: string; 57 | }>`query Q9 { test }` 58 | 59 | gql< 60 | { 61 | test: string; 62 | }, 63 | { 64 | test: string; 65 | } 66 | >` 67 | query Q10 { 68 | test 69 | } 70 | `; 71 | 72 | // prettier-ignore 73 | gql 74 | ` 75 | query Q11 { 76 | test 77 | } 78 | `; 79 | 80 | export {}; 81 | -------------------------------------------------------------------------------- /src/language-server/__tests__/fixtures/documents/templateWithComment.ts: -------------------------------------------------------------------------------- 1 | // hint for reading the snapshots generated by this file: 2 | // it is important to check that a rule doesn't only enter `meta.embedded.block.graphql` 3 | // but also leaves it again 4 | 5 | `#NormalComment 6 | query Foo {test}`; 7 | 8 | `#graphql 9 | query Q1 {test}`; 10 | 11 | ` # graphql 12 | query Q2 {test}`; 13 | 14 | `# GraphQL 15 | query Q3 { 16 | test 17 | }`; 18 | 19 | `#gql 20 | # normal comment 21 | query Q4 { 22 | test 23 | }`; 24 | 25 | `#graphql 26 | query Q5 { 27 | test 28 | }`; 29 | 30 | // syntax highlighting cannot work in all examples after this - textmate grammars don't work over multiple lines like this 31 | ` 32 | 33 | # graphql 34 | 35 | query Q6 { 36 | test 37 | } 38 | `; 39 | -------------------------------------------------------------------------------- /src/language-server/config/__tests__/config.ts: -------------------------------------------------------------------------------- 1 | import { ClientConfig, parseApolloConfig } from "../"; 2 | import { URI } from "vscode-uri"; 3 | 4 | describe("ApolloConfig", () => { 5 | describe("confifDirURI", () => { 6 | it("properly parses dir paths for configDirURI", () => { 7 | const uri = URI.parse("/test/dir/name"); 8 | const config = parseApolloConfig({ client: { service: "hai" } }, uri); 9 | // can be either /test/dir/name or \\test\\dir\\name depending on platform 10 | // this difference is fine :) 11 | expect(config?.configDirURI?.fsPath).toMatch( 12 | /\/test\/dir\/name|\\test\\dir\\name/, 13 | ); 14 | }); 15 | it("properly parses filepaths for configDirURI", () => { 16 | const uri = URI.parse("/test/dir/name/apollo.config.js"); 17 | const config = parseApolloConfig( 18 | { 19 | client: { service: "hai" }, 20 | }, 21 | uri, 22 | ); 23 | // can be either /test/dir/name or \\test\\dir\\name depending on platform 24 | // this difference is fine :) 25 | expect(config?.configDirURI?.fsPath).toMatch( 26 | /\/test\/dir\/name|\\test\\dir\\name/, 27 | ); 28 | }); 29 | }); 30 | 31 | describe("variant", () => { 32 | it("gets default variant when none is set", () => { 33 | const config = parseApolloConfig({ 34 | client: { service: "hai" }, 35 | }); 36 | expect(config?.variant).toEqual("current"); 37 | }); 38 | 39 | it("gets variant from service specifier", () => { 40 | const config = parseApolloConfig({ 41 | client: { service: "hai@master" }, 42 | }); 43 | expect(config?.variant).toEqual("master"); 44 | }); 45 | 46 | it("can set and override variants", () => { 47 | const config = parseApolloConfig({ 48 | client: { service: "hai@master" }, 49 | }); 50 | config!.variant = "new"; 51 | expect(config?.variant).toEqual("new"); 52 | }); 53 | }); 54 | }); 55 | -------------------------------------------------------------------------------- /src/language-server/config/cache-busting-resolver.types.ts: -------------------------------------------------------------------------------- 1 | import { pathToFileURL } from "node:url"; 2 | 3 | export type ImportAttributes = 4 | | { 5 | as: `cachebust:${Format}`; 6 | contents: string; 7 | format: Format; 8 | } 9 | | { as?: undefined }; 10 | 11 | export type ImportAssertions = 12 | | { 13 | as: `cachebust:${Format}`; 14 | [key: string]: string; 15 | } 16 | | { as?: undefined }; 17 | 18 | export type Format = 19 | | "builtin" 20 | | "commonjs" 21 | | "json" 22 | | "module" 23 | | "wasm" 24 | | null 25 | | undefined; 26 | 27 | export interface LegacyResolveContext { 28 | conditions: string[]; 29 | importAssertions: ImportAssertions; 30 | parentURL?: string; 31 | } 32 | 33 | export interface ResolveContext { 34 | conditions: string[]; 35 | importAttributes: ImportAttributes; 36 | parentURL?: string; 37 | } 38 | 39 | export interface LegacyImportContext { 40 | conditions: string[]; 41 | importAssertions: ImportAssertions; 42 | format: Format; 43 | } 44 | export interface ImportContext { 45 | conditions: string[]; 46 | importAttributes: ImportAttributes; 47 | format: Format; 48 | } 49 | 50 | export interface ResolutionResult { 51 | format: Format; 52 | importAttributes?: ImportAttributes; 53 | shortCircuit?: boolean; 54 | url: string; 55 | } 56 | 57 | export interface LoadResult { 58 | format: Format; 59 | shortCircuit?: boolean; 60 | source: string; 61 | } 62 | 63 | export {}; 64 | -------------------------------------------------------------------------------- /src/language-server/config/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./utils"; 2 | export * from "./config"; 3 | export * from "./loadConfig"; 4 | -------------------------------------------------------------------------------- /src/language-server/config/utils.ts: -------------------------------------------------------------------------------- 1 | import { 2 | ApolloConfig, 3 | ClientConfig, 4 | ClientServiceConfig, 5 | LocalServiceConfig, 6 | ParsedApolloConfigFormat, 7 | } from "./config"; 8 | import { ServiceSpecifier, ServiceIDAndTag } from "../engine"; 9 | 10 | export function isClientConfig(config: ApolloConfig): config is ClientConfig { 11 | return config instanceof ClientConfig; 12 | } 13 | 14 | // checks the `config.client.service` object for a localSchemaFile 15 | export function isLocalServiceConfig( 16 | config: ClientServiceConfig, 17 | ): config is LocalServiceConfig { 18 | return !!(config as LocalServiceConfig).localSchemaFile; 19 | } 20 | 21 | export function getServiceFromKey(key?: string) { 22 | if (key) { 23 | const [type, service] = key.split(":"); 24 | if (type === "service") return service; 25 | } 26 | return; 27 | } 28 | 29 | export function getGraphIdFromConfig(config: ParsedApolloConfigFormat) { 30 | if (config.client) { 31 | if (typeof config.client.service === "string") { 32 | return parseServiceSpecifier( 33 | config.client.service as ServiceSpecifier, 34 | )[0]; 35 | } 36 | return config.client.service && config.client.service.name; 37 | } else { 38 | return undefined; 39 | } 40 | } 41 | 42 | export function parseServiceSpecifier(specifier: ServiceSpecifier) { 43 | const [id, tag] = specifier.split("@").map((x) => x.trim()); 44 | return [id, tag] as ServiceIDAndTag; 45 | } 46 | -------------------------------------------------------------------------------- /src/language-server/config/which.d.ts: -------------------------------------------------------------------------------- 1 | declare module "which" { 2 | interface Options { 3 | /** Use instead of the PATH environment variable. */ 4 | path?: string; 5 | /** Use instead of the PATHEXT environment variable. */ 6 | pathExt?: string; 7 | /** Return all matches, instead of just the first one. Note that this means the function returns an array of strings instead of a single string. */ 8 | all?: boolean; 9 | } 10 | 11 | function which(cmd: string, options?: Options): number; 12 | namespace which { 13 | function sync( 14 | cmd: string, 15 | options?: Options & { nothrow?: boolean }, 16 | ): string | null; 17 | } 18 | export = which; 19 | } 20 | -------------------------------------------------------------------------------- /src/language-server/engine/operations/frontendUrlRoot.ts: -------------------------------------------------------------------------------- 1 | import { TypedDocumentNode } from "@apollo/client/core"; 2 | import gql from "graphql-tag"; 3 | import type { 4 | FrontendUrlRootQuery, 5 | FrontendUrlRootQueryVariables, 6 | } from "src/language-server/graphqlTypes"; 7 | 8 | export const FRONTEND_URL_ROOT: TypedDocumentNode< 9 | FrontendUrlRootQuery, 10 | FrontendUrlRootQueryVariables 11 | > = gql` 12 | query FrontendUrlRoot { 13 | frontendUrlRoot 14 | } 15 | `; 16 | -------------------------------------------------------------------------------- /src/language-server/engine/operations/schemaTagsAndFieldStats.ts: -------------------------------------------------------------------------------- 1 | import { TypedDocumentNode } from "@apollo/client/core"; 2 | import gql from "graphql-tag"; 3 | import type { 4 | SchemaTagsAndFieldStatsQuery, 5 | SchemaTagsAndFieldStatsQueryVariables, 6 | } from "src/language-server/graphqlTypes"; 7 | 8 | export const SCHEMA_TAGS_AND_FIELD_STATS: TypedDocumentNode< 9 | SchemaTagsAndFieldStatsQuery, 10 | SchemaTagsAndFieldStatsQueryVariables 11 | > = gql` 12 | query SchemaTagsAndFieldStats($id: ID!) { 13 | service(id: $id) { 14 | schemaTags { 15 | tag 16 | } 17 | stats(from: "-86400", to: "-0") { 18 | fieldLatencies { 19 | groupBy { 20 | parentType 21 | fieldName 22 | } 23 | metrics { 24 | fieldHistogram { 25 | durationMs(percentile: 0.95) 26 | } 27 | } 28 | } 29 | } 30 | } 31 | } 32 | `; 33 | -------------------------------------------------------------------------------- /src/language-server/errors/logger.ts: -------------------------------------------------------------------------------- 1 | import { GraphQLError } from "graphql"; 2 | import path from "path"; 3 | 4 | // ToolError is used for errors that are part of the expected flow 5 | // and for which a stack trace should not be printed 6 | 7 | export class ToolError extends Error { 8 | name: string = "ToolError"; 9 | 10 | constructor(message: string) { 11 | super(message); 12 | this.message = message; 13 | } 14 | } 15 | 16 | const isRunningFromXcodeScript = process.env.XCODE_VERSION_ACTUAL; 17 | 18 | export function logError(error: Error) { 19 | if (error instanceof ToolError) { 20 | logErrorMessage(error.message); 21 | } else if (error instanceof GraphQLError) { 22 | const fileName = error.source && error.source.name; 23 | if (error.locations) { 24 | for (const location of error.locations) { 25 | logErrorMessage(error.message, fileName, location.line); 26 | } 27 | } else { 28 | logErrorMessage(error.message, fileName); 29 | } 30 | } else { 31 | console.error(error.stack); 32 | } 33 | } 34 | 35 | export function logErrorMessage( 36 | message: string, 37 | fileName?: string, 38 | lineNumber?: number, 39 | ) { 40 | if (isRunningFromXcodeScript) { 41 | if (fileName && lineNumber) { 42 | // Prefixing error output with file name, line and 'error: ', 43 | // so Xcode will associate it with the right file and display the error inline 44 | console.error(`${fileName}:${lineNumber}: error: ${message}`); 45 | } else { 46 | // Prefixing error output with 'error: ', so Xcode will display it as an error 47 | console.error(`error: ${message}`); 48 | } 49 | } else { 50 | if (fileName) { 51 | const truncatedFileName = 52 | "/" + fileName.split(path.sep).slice(-4).join(path.sep); 53 | console.error(`...${truncatedFileName}: ${message}`); 54 | } else { 55 | console.error(`error: ${message}`); 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/language-server/fileSet.ts: -------------------------------------------------------------------------------- 1 | import { minimatch } from "minimatch"; 2 | import { globSync } from "glob"; 3 | import { invariant } from "../tools"; 4 | import { URI } from "vscode-uri"; 5 | import { normalizeURI, withUnixSeparator } from "./utilities"; 6 | import { resolve } from "path"; 7 | 8 | export class FileSet { 9 | private rootURI: URI; 10 | private includes: string[]; 11 | private excludes: string[]; 12 | 13 | constructor({ 14 | rootURI, 15 | includes, 16 | excludes, 17 | }: { 18 | rootURI: URI; 19 | includes: string[]; 20 | excludes: string[]; 21 | }) { 22 | invariant(rootURI, `Must provide "rootURI".`); 23 | invariant(includes, `Must provide "includes".`); 24 | invariant(excludes, `Must provide "excludes".`); 25 | 26 | this.rootURI = rootURI; 27 | this.includes = includes; 28 | this.excludes = excludes; 29 | } 30 | 31 | includesFile(filePath: string): boolean { 32 | const normalizedFilePath = normalizeURI(filePath); 33 | 34 | return ( 35 | this.includes.some((include) => { 36 | return minimatch( 37 | normalizedFilePath, 38 | withUnixSeparator(resolve(this.rootURI.fsPath, include)), 39 | ); 40 | }) && 41 | !this.excludes.some((exclude) => { 42 | return minimatch( 43 | normalizedFilePath, 44 | withUnixSeparator(resolve(this.rootURI.fsPath, exclude)), 45 | ); 46 | }) 47 | ); 48 | } 49 | 50 | allFiles(): string[] { 51 | const joinedIncludes = 52 | this.includes.length == 1 53 | ? this.includes[0] 54 | : // since glob.sync takes a single pattern, but we allow an array of `includes`, we can join all the 55 | // `includes` globs into a single pattern and pass to glob.sync. The `ignore` option does, however, allow 56 | // an array of globs to ignore, so we can pass it in directly 57 | `{${this.includes.join(",")}}`; 58 | 59 | return globSync(joinedIncludes, { 60 | cwd: this.rootURI.fsPath, 61 | absolute: true, 62 | ignore: this.excludes, 63 | }).map(normalizeURI); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/language-server/format.ts: -------------------------------------------------------------------------------- 1 | import moment from "moment"; 2 | 3 | export function formatMS( 4 | ms: number, 5 | d: number, 6 | allowMicros = false, 7 | allowNanos = true, 8 | ) { 9 | if (ms === 0 || ms === null) return "0"; 10 | const bounds = [ 11 | moment.duration(1, "hour").asMilliseconds(), 12 | moment.duration(1, "minute").asMilliseconds(), 13 | moment.duration(1, "second").asMilliseconds(), 14 | 1, 15 | 0.001, 16 | 0.000001, 17 | ]; 18 | const units = ["hr", "min", "s", "ms", "μs", "ns"]; 19 | 20 | const makeSmallNumbersNice = (f: number) => { 21 | if (f >= 100) return f.toFixed(0); 22 | if (f >= 10) return f.toFixed(1); 23 | if (f === 0) return "0"; 24 | return f.toFixed(2); 25 | }; 26 | 27 | const bound = bounds.find((b) => b <= ms) || bounds[bounds.length - 1]; 28 | const boundIndex = bounds.indexOf(bound); 29 | const unit = boundIndex >= 0 ? units[boundIndex] : ""; 30 | 31 | if ((unit === "μs" || unit === "ns") && !allowMicros) { 32 | return "< 1ms"; 33 | } 34 | if (unit === "ns" && !allowNanos) { 35 | return "< 1µs"; 36 | } 37 | const value = 38 | typeof d !== "undefined" 39 | ? (ms / bound).toFixed(d) 40 | : makeSmallNumbersNice(ms / bound); 41 | 42 | // if something is rounded to 1000 and not reduced this will catch and reduce it 43 | if ((value === "1000" || value === "1000.0") && boundIndex >= 1) { 44 | return `1${units[boundIndex - 1]}`; 45 | } 46 | 47 | return `${value}${unit}`; 48 | } 49 | -------------------------------------------------------------------------------- /src/language-server/index.ts: -------------------------------------------------------------------------------- 1 | // Exports for consuming APIs 2 | 3 | export { getValidationErrors } from "./errors/validation"; 4 | export { ToolError } from "./errors/logger"; 5 | export { LoadingHandler } from "./loadingHandler"; 6 | 7 | // projects 8 | export { GraphQLProject } from "./project/base"; 9 | export { isClientProject, GraphQLClientProject } from "./project/client"; 10 | 11 | // GraphQLSchemaProvider 12 | export { 13 | GraphQLSchemaProvider, 14 | schemaProviderFromConfig, 15 | } from "./providers/schema"; 16 | 17 | // Engine 18 | export * from "./engine"; 19 | 20 | // Config 21 | export * from "./config"; 22 | 23 | // Generated types 24 | import * as graphqlTypes from "./graphqlTypes"; 25 | export { graphqlTypes }; 26 | 27 | // debug logger 28 | export { Debug } from "./utilities"; 29 | -------------------------------------------------------------------------------- /src/language-server/loadingHandler.ts: -------------------------------------------------------------------------------- 1 | import { LanguageServerNotifications as Notifications } from "../messages"; 2 | import { Connection, NotificationType } from "vscode-languageserver/node"; 3 | 4 | // XXX I think we want to combine this into an interface 5 | // with the errors tooling as well 6 | 7 | export interface LoadingHandler { 8 | handle(message: string, value: Promise): Promise; 9 | handleSync(message: string, value: () => T): T; 10 | showError(message: string): void; 11 | } 12 | 13 | export class LanguageServerLoadingHandler implements LoadingHandler { 14 | constructor(private connection: Connection) {} 15 | private latestLoadingToken = 0; 16 | async handle(message: string, value: Promise): Promise { 17 | const token = this.latestLoadingToken; 18 | this.latestLoadingToken += 1; 19 | this.connection.sendNotification(Notifications.Loading, { message, token }); 20 | try { 21 | const ret = await value; 22 | this.connection.sendNotification(Notifications.LoadingComplete, token); 23 | return ret; 24 | } catch (e) { 25 | this.connection.sendNotification(Notifications.LoadingComplete, token); 26 | this.showError(`Error in "${message}": ${e}`); 27 | throw e; 28 | } 29 | } 30 | handleSync(message: string, value: () => T): T { 31 | const token = this.latestLoadingToken; 32 | this.latestLoadingToken += 1; 33 | this.connection.sendNotification(Notifications.Loading, { message, token }); 34 | try { 35 | const ret = value(); 36 | this.connection.sendNotification(Notifications.LoadingComplete, token); 37 | return ret; 38 | } catch (e) { 39 | Notifications.LoadingComplete, 40 | this.showError(`Error in "${message}": ${e}`); 41 | throw e; 42 | } 43 | } 44 | showError(message: string) { 45 | this.connection.window.showErrorMessage(message); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/language-server/providers/schema/base.ts: -------------------------------------------------------------------------------- 1 | import { GraphQLSchema } from "graphql"; 2 | import { NotificationHandler } from "vscode-languageserver/node"; 3 | 4 | export interface SchemaResolveConfig { 5 | tag?: string; 6 | force?: boolean; 7 | } 8 | export type SchemaChangeUnsubscribeHandler = () => void; 9 | export interface GraphQLSchemaProvider { 10 | resolveSchema(config?: SchemaResolveConfig): Promise; 11 | onSchemaChange( 12 | handler: NotificationHandler, 13 | ): SchemaChangeUnsubscribeHandler; 14 | resolveFederatedServiceSDL(): Promise; 15 | } 16 | -------------------------------------------------------------------------------- /src/language-server/providers/schema/index.ts: -------------------------------------------------------------------------------- 1 | import { 2 | GraphQLSchemaProvider, 3 | SchemaChangeUnsubscribeHandler, 4 | SchemaResolveConfig, 5 | } from "./base"; 6 | import { 7 | ApolloConfig, 8 | isClientConfig, 9 | isLocalServiceConfig, 10 | ClientConfig, 11 | } from "../../config"; 12 | 13 | import { EndpointSchemaProvider } from "./endpoint"; 14 | import { EngineSchemaProvider } from "./engine"; 15 | import { FileSchemaProvider } from "./file"; 16 | import { ClientIdentity } from "../../engine"; 17 | 18 | export { 19 | GraphQLSchemaProvider, 20 | SchemaChangeUnsubscribeHandler, 21 | SchemaResolveConfig, 22 | }; 23 | 24 | export function schemaProviderFromConfig( 25 | config: ApolloConfig, 26 | clientIdentity: ClientIdentity, // engine provider needs this 27 | ): GraphQLSchemaProvider { 28 | if (isClientConfig(config)) { 29 | if (typeof config.client.service === "string") { 30 | return new EngineSchemaProvider(config, clientIdentity); 31 | } 32 | 33 | if (config.client.service) { 34 | if (isLocalServiceConfig(config.client.service)) { 35 | const isListOfSchemaFiles = Array.isArray( 36 | config.client.service.localSchemaFile, 37 | ); 38 | return new FileSchemaProvider( 39 | isListOfSchemaFiles 40 | ? { paths: config.client.service.localSchemaFile as string[] } 41 | : { 42 | path: config.client.service.localSchemaFile as string, 43 | }, 44 | config.configDirURI, 45 | ); 46 | } 47 | 48 | return new EndpointSchemaProvider(config.client.service); 49 | } 50 | } 51 | 52 | if (config.graph && config.engine) { 53 | return new EngineSchemaProvider(config as ClientConfig, clientIdentity); 54 | } 55 | 56 | throw new Error( 57 | "No schema provider was created, because the project type was unable to be resolved from your config. Please add either a client or service config. For more information, please refer to https://go.apollo.dev/t/config", 58 | ); 59 | } 60 | -------------------------------------------------------------------------------- /src/language-server/typings/graphql.d.ts: -------------------------------------------------------------------------------- 1 | import { 2 | ASTNode, 3 | TypeSystemDefinitionNode, 4 | TypeSystemExtensionNode, 5 | FragmentDefinitionNode, 6 | OperationDefinitionNode, 7 | } from "graphql"; 8 | 9 | // FIXME: We should add proper type guards for these predicate functions 10 | // to `@types/graphql`. 11 | declare module "graphql/language/predicates" { 12 | function isExecutableDefinitionNode( 13 | node: ASTNode, 14 | ): node is OperationDefinitionNode | FragmentDefinitionNode; 15 | function isTypeSystemDefinitionNode( 16 | node: ASTNode, 17 | ): node is TypeSystemDefinitionNode; 18 | function isTypeSystemExtensionNode( 19 | node: ASTNode, 20 | ): node is TypeSystemExtensionNode; 21 | } 22 | 23 | declare module "graphql/validation/validate" { 24 | interface ValidationContext { 25 | _fragments: { [fragmentName: string]: FragmentDefinitionNode }; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/language-server/utilities/__tests__/uri.ts: -------------------------------------------------------------------------------- 1 | import { normalizeURI } from "../uri"; 2 | 3 | describe("Unix URIs", () => { 4 | // this is the format that `glob` returns on unix 5 | const uriToMatchForUnix = "/test/myFile.js"; 6 | 7 | // single forward slash (unix) 8 | it("handles /Users/me URIs", () => { 9 | const uri = "/test/myFile.js"; 10 | const parsed = normalizeURI(uri); 11 | expect(parsed).toEqual(uriToMatchForUnix); 12 | }); 13 | 14 | // single escaped backslash 15 | // treat these as forward slashes? 16 | it("handles \\Users\\me URIs", () => { 17 | const uri = "\\test\\myFile.js"; 18 | const parsed = normalizeURI(uri); 19 | expect(parsed).toEqual(uriToMatchForUnix); 20 | }); 21 | }); 22 | 23 | describe("Windows URIs", () => { 24 | // this is the format that `glob` returns for windows 25 | const uriToMatchForWindows = "c:/test/myFile.js"; 26 | 27 | // this format is sent by the native extension notification system on windows 28 | it("handles file:///c%3A/ URIs", () => { 29 | const uri = "file:///c%3A/test/myFile.js"; 30 | const parsed = normalizeURI(uri); 31 | expect(parsed).toEqual(uriToMatchForWindows); 32 | }); 33 | 34 | // same as above without URI encoded : 35 | it("handles handles file:///c:/ URIs", () => { 36 | const uri = "file:///c:/test/myFile.js"; 37 | const parsed = normalizeURI(uri); 38 | expect(parsed).toEqual(uriToMatchForWindows); 39 | }); 40 | 41 | // result of glob.sync 42 | it("handles c:/ URIs", () => { 43 | const uri = "c:/test/myFile.js"; 44 | const parsed = normalizeURI(uri); 45 | expect(parsed).toEqual(uriToMatchForWindows); 46 | }); 47 | 48 | // from status bar notification 49 | // single (escaped) backslash 50 | it("handles c:\\ URIs", () => { 51 | const uri = "c:\\test\\myFile.js"; 52 | const parsed = normalizeURI(uri); 53 | expect(parsed).toEqual(uriToMatchForWindows); 54 | }); 55 | }); 56 | -------------------------------------------------------------------------------- /src/language-server/utilities/debouncer.ts: -------------------------------------------------------------------------------- 1 | import debounce from "lodash.debounce"; 2 | 3 | export function debounceHandler( 4 | handler: (...args: any[]) => any, 5 | leading: boolean = true, 6 | ) { 7 | return debounce(handler, 250, { leading }); 8 | } 9 | -------------------------------------------------------------------------------- /src/language-server/utilities/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./debouncer"; 2 | export * from "./uri"; 3 | export { Debug } from "./debug"; 4 | -------------------------------------------------------------------------------- /src/language-server/utilities/languageIdForExtension.ts: -------------------------------------------------------------------------------- 1 | import { 2 | FileExtension, 3 | LanguageIdExtensionMap, 4 | supportedLanguageIds, 5 | } from "../../tools/utilities/languageInformation"; 6 | 7 | let languageIdPerExtension: Record | undefined; 8 | let supportedExtensions: FileExtension[] | undefined; 9 | 10 | export function setLanguageIdExtensionMap(map: LanguageIdExtensionMap) { 11 | languageIdPerExtension = Object.fromEntries( 12 | Object.entries(map).flatMap(([languageId, extensions]) => 13 | extensions.map((extension) => [extension, languageId]), 14 | ), 15 | ); 16 | supportedExtensions = supportedLanguageIds.flatMap( 17 | (languageId) => map[languageId], 18 | ); 19 | } 20 | 21 | /** 22 | * @throws if called before the language server has received options via `onInitialize`. 23 | */ 24 | export function getLanguageIdForExtension(ext: FileExtension) { 25 | if (!languageIdPerExtension) { 26 | throw new Error("LanguageIdExtensionMap not set"); 27 | } 28 | return languageIdPerExtension[ext]; 29 | } 30 | 31 | /** 32 | * @throws if called before the language server has received options via `onInitialize`. 33 | */ 34 | export function getSupportedExtensions() { 35 | if (!supportedExtensions) { 36 | throw new Error("LanguageIdExtensionMap not set"); 37 | } 38 | return supportedExtensions; 39 | } 40 | -------------------------------------------------------------------------------- /src/language-server/utilities/uri.ts: -------------------------------------------------------------------------------- 1 | import { URI } from "vscode-uri"; 2 | 3 | export const withUnixSeparator = (uriString: string) => 4 | uriString.split(/[\/\\]/).join("/"); 5 | 6 | export const normalizeURI = (uriString: string) => { 7 | let parsed; 8 | if (uriString.indexOf("file:///") === 0) { 9 | parsed = URI.file(URI.parse(uriString).fsPath); 10 | } else if (uriString.match(/^[a-zA-Z]:[\/\\].*/)) { 11 | // uri with a drive prefix but not file:/// 12 | parsed = URI.file( 13 | URI.parse("file:///" + withUnixSeparator(uriString)).fsPath, 14 | ); 15 | } else { 16 | parsed = URI.parse(withUnixSeparator(uriString)); 17 | } 18 | return withUnixSeparator(parsed.fsPath); 19 | }; 20 | -------------------------------------------------------------------------------- /src/languageServerClient.ts: -------------------------------------------------------------------------------- 1 | import { 2 | ServerOptions, 3 | TransportKind, 4 | LanguageClientOptions, 5 | LanguageClient, 6 | RevealOutputChannelOn, 7 | } from "vscode-languageclient/node"; 8 | import { workspace, OutputChannel } from "vscode"; 9 | import { supportedLanguageIds } from "./tools/utilities/languageInformation"; 10 | import type { InitializationOptions } from "./language-server/server"; 11 | import { getLangugageInformation } from "./tools/utilities/getLanguageInformation"; 12 | 13 | const { version, referenceID } = require("../package.json"); 14 | 15 | const languageIdExtensionMap = getLangugageInformation(); 16 | const supportedExtensions = supportedLanguageIds.flatMap( 17 | (id) => languageIdExtensionMap[id], 18 | ); 19 | 20 | export function getLanguageServerClient( 21 | serverModule: string, 22 | outputChannel: OutputChannel, 23 | ) { 24 | const env = { 25 | APOLLO_CLIENT_NAME: "Apollo VS Code", 26 | APOLLO_CLIENT_VERSION: version, 27 | APOLLO_CLIENT_REFERENCE_ID: referenceID, 28 | NODE_TLS_REJECT_UNAUTHORIZED: 0, 29 | }; 30 | 31 | const debugOptions = { 32 | execArgv: ["--nolazy", "--inspect=6009"], 33 | env, 34 | }; 35 | 36 | const serverOptions: ServerOptions = { 37 | run: { 38 | module: serverModule, 39 | transport: TransportKind.ipc, 40 | options: { 41 | env, 42 | }, 43 | }, 44 | debug: { 45 | module: serverModule, 46 | transport: TransportKind.ipc, 47 | options: debugOptions, 48 | }, 49 | }; 50 | 51 | const clientOptions: LanguageClientOptions = { 52 | documentSelector: supportedLanguageIds, 53 | synchronize: { 54 | fileEvents: [ 55 | workspace.createFileSystemWatcher("**/{.env?(.local)}"), 56 | workspace.createFileSystemWatcher("**/apollo.config.{json,yml,yaml}"), 57 | workspace.createFileSystemWatcher( 58 | "**/*{" + supportedExtensions.join(",") + "}", 59 | ), 60 | ], 61 | }, 62 | outputChannel, 63 | revealOutputChannelOn: workspace 64 | .getConfiguration("apollographql") 65 | .get("debug.revealOutputOnLanguageServerError") 66 | ? RevealOutputChannelOn.Error 67 | : RevealOutputChannelOn.Never, 68 | initializationOptions: { 69 | languageIdExtensionMap, 70 | } satisfies InitializationOptions, 71 | }; 72 | 73 | return new LanguageClient( 74 | "apollographql", 75 | "Apollo GraphQL", 76 | serverOptions, 77 | clientOptions, 78 | ); 79 | } 80 | -------------------------------------------------------------------------------- /src/messages.ts: -------------------------------------------------------------------------------- 1 | import { QuickPickItem } from "vscode"; 2 | import { NotificationType, RequestType } from "vscode-jsonrpc"; 3 | import { Range } from "vscode-languageclient/node"; 4 | 5 | export interface TypeStats { 6 | service?: number; 7 | client?: number; 8 | total?: number; 9 | } 10 | 11 | export type ProjectStats = 12 | | { 13 | type: string; 14 | loaded: true; 15 | serviceId?: string; 16 | types?: TypeStats; 17 | tag?: string; 18 | lastFetch?: number; 19 | } 20 | | { loaded: false }; 21 | 22 | export type EngineDecoration = 23 | | { 24 | type: "text"; 25 | document: string; 26 | message: string; 27 | range: Range; 28 | } 29 | | { 30 | type: "runGlyph"; 31 | document: string; 32 | range: Range; 33 | hoverMessage: string; 34 | }; 35 | 36 | export const LanguageServerRequests = { 37 | FileStats: new RequestType<{ uri: string }, ProjectStats, unknown>( 38 | "apollographql/fileStats", 39 | ), 40 | }; 41 | 42 | /** 43 | * Notifications sent to the language server 44 | */ 45 | export const LanguageServerCommands = { 46 | GetStats: new NotificationType<{ uri: string }>("apollographql/getStats"), 47 | ReloadService: new NotificationType("apollographql/reloadService"), 48 | TagSelected: new NotificationType("apollographql/tagSelected"), 49 | }; 50 | 51 | /** 52 | * Notifications sent from the language server 53 | */ 54 | export const LanguageServerNotifications = { 55 | StatsLoaded: new NotificationType("apollographql/statsLoaded"), 56 | ConfigFilesFound: new NotificationType( 57 | "apollographql/configFilesFound", 58 | ), 59 | TagsLoaded: new NotificationType("apollographql/tagsLoaded"), 60 | LoadingComplete: new NotificationType( 61 | "apollographql/loadingComplete", 62 | ), 63 | Loading: new NotificationType<{ 64 | message: string; 65 | token: number; 66 | }>("apollographql/loading"), 67 | EngineDecorations: new NotificationType<{ 68 | decorations: EngineDecoration[]; 69 | }>("apollographql/engineDecorations"), 70 | ServerDebugMessage: new NotificationType<{ 71 | type: "info" | "warning" | "error" | "errorTelemetry"; 72 | message: string; 73 | stack?: string; 74 | }>("serverDebugMessage"), 75 | }; 76 | -------------------------------------------------------------------------------- /src/statusBar.ts: -------------------------------------------------------------------------------- 1 | import { window, StatusBarAlignment } from "vscode"; 2 | 3 | interface LoadingInput { 4 | hasActiveTextEditor: boolean; 5 | } 6 | 7 | interface StateChangeInput extends LoadingInput { 8 | text: string; 9 | tooltip?: string; 10 | } 11 | 12 | export default class ApolloStatusBar { 13 | public statusBarItem = window.createStatusBarItem(StatusBarAlignment.Right); 14 | 15 | static loadingStateText = "Apollo $(rss)"; 16 | static loadedStateText = "Apollo $(rocket)"; 17 | static warningText = "Apollo $(alert)"; 18 | 19 | constructor({ hasActiveTextEditor }: LoadingInput) { 20 | this.showLoadingState({ hasActiveTextEditor }); 21 | this.statusBarItem.command = "apollographql/showStats"; 22 | } 23 | 24 | protected changeState({ 25 | hasActiveTextEditor, 26 | text, 27 | tooltip, 28 | }: StateChangeInput) { 29 | if (!hasActiveTextEditor) { 30 | this.statusBarItem.hide(); 31 | return; 32 | } 33 | 34 | this.statusBarItem.text = text; 35 | this.statusBarItem.tooltip = tooltip; 36 | this.statusBarItem.show(); 37 | } 38 | 39 | public showLoadingState({ hasActiveTextEditor }: LoadingInput) { 40 | this.changeState({ 41 | hasActiveTextEditor, 42 | text: ApolloStatusBar.loadingStateText, 43 | }); 44 | } 45 | 46 | public showLoadedState({ hasActiveTextEditor }: LoadingInput) { 47 | this.changeState({ 48 | hasActiveTextEditor, 49 | text: ApolloStatusBar.loadedStateText, 50 | }); 51 | } 52 | 53 | public showWarningState({ 54 | hasActiveTextEditor, 55 | tooltip, 56 | }: LoadingInput & { tooltip: string }) { 57 | this.changeState({ 58 | hasActiveTextEditor, 59 | text: ApolloStatusBar.warningText, 60 | tooltip, 61 | }); 62 | } 63 | 64 | public dispose() { 65 | this.statusBarItem.dispose(); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/tools/__tests__/snapshotSerializers/astSerializer.ts: -------------------------------------------------------------------------------- 1 | import { ASTNode, print } from "graphql"; 2 | import { Plugin } from "pretty-format"; 3 | 4 | const plugin: Plugin = { 5 | test(value) { 6 | return value && typeof value.kind === "string"; 7 | }, 8 | 9 | serialize(value: ASTNode, _config, indentation): string { 10 | return ( 11 | indentation + 12 | print(value) 13 | .trim() 14 | .replace(/\n/g, "\n" + indentation) 15 | ); 16 | }, 17 | }; 18 | 19 | export default plugin; 20 | -------------------------------------------------------------------------------- /src/tools/__tests__/snapshotSerializers/graphQLTypeSerializer.ts: -------------------------------------------------------------------------------- 1 | import { isNamedType, GraphQLNamedType, printType } from "graphql"; 2 | import { Plugin } from "pretty-format"; 3 | 4 | const plugin: Plugin = { 5 | test(value) { 6 | return value && isNamedType(value); 7 | }, 8 | 9 | serialize(value: GraphQLNamedType): string { 10 | return printType(value); 11 | }, 12 | }; 13 | 14 | export default plugin; 15 | -------------------------------------------------------------------------------- /src/tools/index.ts: -------------------------------------------------------------------------------- 1 | import "../env"; 2 | 3 | export * from "./utilities"; 4 | 5 | export * from "./schema"; 6 | export * from "./buildServiceDefinition"; 7 | -------------------------------------------------------------------------------- /src/tools/schema/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./resolverMap"; 2 | export * from "./resolveObject"; 3 | -------------------------------------------------------------------------------- /src/tools/schema/resolveObject.ts: -------------------------------------------------------------------------------- 1 | import { GraphQLResolveInfo, FieldNode } from "graphql"; 2 | 3 | export type GraphQLObjectResolver = ( 4 | source: TSource, 5 | fields: Record>, 6 | context: TContext, 7 | info: GraphQLResolveInfo, 8 | ) => any; 9 | 10 | declare module "graphql/type/definition" { 11 | interface GraphQLObjectType { 12 | resolveObject?: GraphQLObjectResolver; 13 | } 14 | 15 | interface GraphQLObjectTypeConfig { 16 | resolveObject?: GraphQLObjectResolver; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/tools/schema/resolverMap.ts: -------------------------------------------------------------------------------- 1 | import { GraphQLFieldResolver } from "graphql"; 2 | 3 | export interface GraphQLResolverMap { 4 | [typeName: string]: { 5 | [fieldName: string]: 6 | | GraphQLFieldResolver 7 | | { 8 | requires?: string; 9 | resolve: GraphQLFieldResolver; 10 | subscribe?: undefined; 11 | } 12 | | { 13 | requires?: string; 14 | resolve?: undefined; 15 | subscribe: GraphQLFieldResolver; 16 | } 17 | | { 18 | requires?: string; 19 | resolve: GraphQLFieldResolver; 20 | subscribe: GraphQLFieldResolver; 21 | }; 22 | }; 23 | } 24 | -------------------------------------------------------------------------------- /src/tools/utilities/getLanguageInformation.ts: -------------------------------------------------------------------------------- 1 | import * as vscode from "vscode"; 2 | import { 3 | LanguageIdExtensionMap, 4 | minimumKnownExtensions, 5 | } from "./languageInformation"; 6 | 7 | /** 8 | * @returns An object with language identifiers as keys and file extensions as values. 9 | * see https://github.com/microsoft/vscode/issues/109919 10 | */ 11 | export function getLangugageInformation(): LanguageIdExtensionMap { 12 | const allKnownExtensions = vscode.extensions.all 13 | .map( 14 | (i) => 15 | i.packageJSON?.contributes?.languages as ( 16 | | undefined 17 | | { 18 | id?: string; 19 | extensions?: string[]; 20 | } 21 | )[], 22 | ) 23 | .flat() 24 | .filter( 25 | (i): i is { id: string; extensions: `.${string}`[] } => 26 | !!(i && i.id && i.extensions?.length), 27 | ) 28 | .reduce>>( 29 | (acc, i) => { 30 | if (!acc[i.id]) acc[i.id] = new Set(); 31 | for (const ext of i.extensions) acc[i.id].add(ext); 32 | return acc; 33 | }, 34 | Object.fromEntries( 35 | Object.entries(minimumKnownExtensions).map(([k, v]) => [k, new Set(v)]), 36 | ), 37 | ); 38 | return Object.fromEntries( 39 | Object.entries(allKnownExtensions).map(([k, v]) => [k, [...v]] as const), 40 | ) as LanguageIdExtensionMap; 41 | } 42 | -------------------------------------------------------------------------------- /src/tools/utilities/graphql.ts: -------------------------------------------------------------------------------- 1 | import { 2 | ASTNode, 3 | TypeDefinitionNode, 4 | TypeExtensionNode, 5 | DocumentNode, 6 | Kind, 7 | } from "graphql"; 8 | 9 | // FIXME: We should add proper type guards for these predicate functions 10 | // to `@types/graphql`. 11 | declare module "graphql/language/predicates" { 12 | function isTypeDefinitionNode(node: ASTNode): node is TypeDefinitionNode; 13 | function isTypeExtensionNode(node: ASTNode): node is TypeExtensionNode; 14 | } 15 | 16 | export function isNode(maybeNode: any): maybeNode is ASTNode { 17 | return maybeNode && typeof maybeNode.kind === "string"; 18 | } 19 | 20 | export function isDocumentNode(node: ASTNode): node is DocumentNode { 21 | return isNode(node) && node.kind === Kind.DOCUMENT; 22 | } 23 | -------------------------------------------------------------------------------- /src/tools/utilities/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./invariant"; 2 | export * from "./predicates"; 3 | export * from "./graphql"; 4 | -------------------------------------------------------------------------------- /src/tools/utilities/invariant.ts: -------------------------------------------------------------------------------- 1 | export function invariant(condition: any, message: string) { 2 | if (!condition) { 3 | throw new Error(message); 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /src/tools/utilities/languageInformation.ts: -------------------------------------------------------------------------------- 1 | const _supportedDocumentTypes = [ 2 | "graphql", 3 | "javascript", 4 | "typescript", 5 | "javascriptreact", 6 | "typescriptreact", 7 | "vue", 8 | "svelte", 9 | "python", 10 | "ruby", 11 | "dart", 12 | "reason", 13 | "elixir", 14 | ] as const; 15 | export type SupportedLanguageIds = (typeof _supportedDocumentTypes)[number]; 16 | export const supportedLanguageIds = 17 | // remove the `readonly` we get from using `as const` 18 | _supportedDocumentTypes as any as SupportedLanguageIds[]; 19 | 20 | export type FileExtension = `.${string}`; 21 | 22 | export const minimumKnownExtensions: Record< 23 | SupportedLanguageIds, 24 | FileExtension[] 25 | > = { 26 | graphql: [".gql", ".graphql", ".graphqls"], 27 | javascript: [".js", ".mjs", ".cjs"], 28 | typescript: [".ts", ".mts", ".cts"], 29 | javascriptreact: [".jsx"], 30 | typescriptreact: [".tsx"], 31 | vue: [".vue"], 32 | svelte: [".svelte"], 33 | python: [".py", ".ipynb"], 34 | ruby: [".rb"], 35 | dart: [".dart"], 36 | reason: [".re"], 37 | elixir: [".ex", ".exs"], 38 | }; 39 | 40 | export type LanguageIdExtensionMap = Record & 41 | typeof minimumKnownExtensions; 42 | -------------------------------------------------------------------------------- /src/tools/utilities/predicates.ts: -------------------------------------------------------------------------------- 1 | export function isNotNullOrUndefined( 2 | value: T | null | undefined, 3 | ): value is T { 4 | return value !== null && typeof value !== "undefined"; 5 | } 6 | -------------------------------------------------------------------------------- /start-ac.mjs: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | // for testing, start a few of these, e.g. with 4 | // while true; do echo "foo\nbar\nbaz" | parallel ./start-ac.mjs; sleep 1; done 5 | 6 | import { connectApolloClientToVSCodeDevTools } from "@apollo/client-devtools-vscode"; 7 | import WebSocket from "ws"; 8 | import { ApolloClient, InMemoryCache } from "@apollo/client/core/index.js"; 9 | import { MockLink } from "@apollo/client/testing/core/index.js"; 10 | import gql from "graphql-tag"; 11 | 12 | globalThis.WebSocket ||= WebSocket; 13 | 14 | const helloWorld = gql` 15 | query { 16 | hello 17 | } 18 | `; 19 | 20 | const link = new MockLink([ 21 | { 22 | request: { query: helloWorld }, 23 | result: { data: { hello: "world" } }, 24 | maxUsageCount: 1000, 25 | }, 26 | { 27 | request: { 28 | query: gql` 29 | query { 30 | hi 31 | } 32 | `, 33 | }, 34 | result: { data: { hi: "universe" } }, 35 | maxUsageCount: 1000, 36 | }, 37 | ]); 38 | const client = new ApolloClient({ 39 | link, 40 | cache: new InMemoryCache(), 41 | devtools: { name: process.argv[2] }, 42 | }); 43 | client.watchQuery({ query: helloWorld }).subscribe({ next() {} }); 44 | const { connectedPromise, disconnect, onCleanup } = 45 | connectApolloClientToVSCodeDevTools( 46 | client, 47 | "ws://localhost:7095", // nosemgrep 48 | ); 49 | console.log("connecting..."); 50 | onCleanup((reason) => 51 | console.log( 52 | "disconnected", 53 | reason, 54 | /* referencing client here to prevent it from getting garbage connected */ client.version, 55 | ), 56 | ); 57 | connectedPromise.then(() => { 58 | console.log("connected"); 59 | // setTimeout(unregister, 5000, "USERLAND_TIMEOUT"); 60 | }); 61 | -------------------------------------------------------------------------------- /syntaxes/graphql.dart.json: -------------------------------------------------------------------------------- 1 | { 2 | "fileTypes": ["dart"], 3 | "injectionSelector": "L:source -string -comment", 4 | "patterns": [ 5 | { 6 | "name": "meta.function-call.dart", 7 | "begin": "\\b(gql)(\\()", 8 | "beginCaptures": { 9 | "1": { 10 | "name": "entity.name.function.dart" 11 | }, 12 | "2": { 13 | "name": "punctuation.definition.arguments.begin.dart" 14 | } 15 | }, 16 | "end": "(\\))", 17 | "endCaptures": { 18 | "1": { 19 | "name": "punctuation.definition.arguments.end.dart" 20 | } 21 | }, 22 | "patterns": [ 23 | { 24 | "name": "taggedTemplates", 25 | "contentName": "meta.embedded.block.graphql", 26 | "begin": "r?(\"\"\"|''')", 27 | "end": "((\\1))", 28 | "patterns": [ 29 | { 30 | "include": "source.graphql" 31 | } 32 | ] 33 | } 34 | ] 35 | } 36 | ], 37 | "scopeName": "inline.graphql.dart" 38 | } 39 | -------------------------------------------------------------------------------- /syntaxes/graphql.ex.json: -------------------------------------------------------------------------------- 1 | { 2 | "fileTypes": ["ex", "exs"], 3 | "injectionSelector": "L:source -string -comment", 4 | "patterns": [ 5 | { 6 | "name": "meta.function-call.elixir", 7 | "begin": "\\b(gql)(\\()", 8 | "beginCaptures": { 9 | "1": { 10 | "name": "entity.name.function.elixir" 11 | }, 12 | "2": { 13 | "name": "punctuation.definition.arguments.begin.elixir" 14 | } 15 | }, 16 | "end": "(\\))", 17 | "endCaptures": { 18 | "1": { 19 | "name": "punctuation.definition.arguments.end.elixir" 20 | } 21 | }, 22 | "patterns": [ 23 | { 24 | "name": "taggedTemplates", 25 | "contentName": "meta.embedded.block.graphql", 26 | "begin": "r?(\"\"\")", 27 | "end": "((\\1))", 28 | "patterns": [ 29 | { 30 | "include": "source.graphql" 31 | } 32 | ] 33 | } 34 | ] 35 | } 36 | ], 37 | "scopeName": "inline.graphql.elixir" 38 | } 39 | -------------------------------------------------------------------------------- /syntaxes/graphql.js.json: -------------------------------------------------------------------------------- 1 | { 2 | "fileTypes": ["js", "jsx", "ts", "tsx", "vue", "svelte"], 3 | "injectionSelector": "L:source -string -comment", 4 | "patterns": [ 5 | { 6 | "contentName": "meta.embedded.block.graphql", 7 | "begin": "(?:Relay\\.QL|gql|graphql(\\.experimental)?)\\s*(?:<.*?>\\s*)?`", 8 | "end": "`", 9 | "patterns": [{ "include": "source.graphql" }] 10 | }, 11 | { 12 | "contentName": "meta.embedded.block.graphql", 13 | "begin": "`(\\s*#[ ]*(gql|graphql|GraphQL))", 14 | "beginCaptures": { 15 | "1": { 16 | "name": "meta.embedded.block.graphql comment.line.graphql.js" 17 | }, 18 | "2": { 19 | "name": "markup.italic" 20 | } 21 | }, 22 | "end": "`", 23 | "patterns": [{ "include": "source.graphql" }] 24 | }, 25 | { 26 | "contentName": "meta.embedded.block.graphql", 27 | "begin": "(?:gql|graphql)\\s*(?:<.*?>\\s*)?\\(\\s*`", 28 | "end": "`\\s*\\)", 29 | "patterns": [{ "include": "source.graphql" }] 30 | }, 31 | { 32 | "contentName": "meta.embedded.block.graphql", 33 | "begin": "(?:\\/\\*[\\s\\*]*(gql|graphql|GraphQL)\\s*\\*\\/)\\s*(`)", 34 | "beginCaptures": { 35 | "1": { 36 | "name": "markup.italic" 37 | } 38 | }, 39 | "end": "`", 40 | "patterns": [{ "include": "source.graphql" }] 41 | } 42 | ], 43 | "scopeName": "inline.graphql" 44 | } 45 | -------------------------------------------------------------------------------- /syntaxes/graphql.lua.json: -------------------------------------------------------------------------------- 1 | { 2 | "fileTypes": ["lua", "luau"], 3 | "injectionSelector": "L:source -string -comment", 4 | "patterns": [ 5 | { 6 | "contentName": "meta.embedded.block.graphql", 7 | "begin": "(--\\[\\[)\\s*(gql)\\s*(\\]\\])\\s*(\\[\\[)", 8 | "beginCaptures": { 9 | "1": { 10 | "name": "comment.block.lua" 11 | }, 12 | "2": { 13 | "name": "entity.name.function.lua" 14 | }, 15 | "3": { 16 | "name": "comment.block.lua" 17 | }, 18 | "4": { 19 | "name": "string.quoted.double.lua" 20 | } 21 | }, 22 | "end": "(\\]\\])", 23 | "endCaptures": { 24 | "1": { 25 | "name": "string.quoted.double.lua" 26 | } 27 | }, 28 | "patterns": [{ "include": "source.graphql" }] 29 | }, 30 | { 31 | "contentName": "meta.embedded.block.graphql", 32 | "begin": "(gql)\\(?\\s*(\\[\\[)", 33 | "beginCaptures": { 34 | "1": { 35 | "name": "entity.name.function.lua" 36 | }, 37 | "2": { 38 | "name": "string.quoted.double.lua" 39 | } 40 | }, 41 | "end": "(\\]\\])", 42 | "endCaptures": { 43 | "1": { 44 | "name": "string.quoted.double.lua" 45 | } 46 | }, 47 | "patterns": [{ "include": "source.graphql" }] 48 | } 49 | ], 50 | "scopeName": "inline.graphql.lua" 51 | } 52 | -------------------------------------------------------------------------------- /syntaxes/graphql.py.json: -------------------------------------------------------------------------------- 1 | { 2 | "fileTypes": ["python"], 3 | "injectionSelector": "L:source -string -comment", 4 | "patterns": [ 5 | { 6 | "name": "meta.function-call.python", 7 | "begin": "\\b(gql)\\s*(\\()", 8 | "beginCaptures": { 9 | "1": { 10 | "name": "meta.function-call.generic.python" 11 | }, 12 | "2": { 13 | "name": "punctuation.definition.arguments.begin.python" 14 | } 15 | }, 16 | "end": "(\\))", 17 | "endCaptures": { 18 | "1": { 19 | "name": "punctuation.definition.arguments.end.python" 20 | } 21 | }, 22 | "patterns": [ 23 | { 24 | "name": "taggedTemplates", 25 | "contentName": "meta.embedded.block.graphql", 26 | "begin": "([bfru]*)((\"(?:\"\")?|'(?:'')?))", 27 | "beginCaptures": { 28 | "1": { 29 | "name": "storage.type.string.python" 30 | }, 31 | "2": { 32 | "name": "string.quoted.multi.python" 33 | }, 34 | "3": { 35 | "name": "punctuation.definition.string.begin.python" 36 | } 37 | }, 38 | "end": "((\\3))", 39 | "endCaptures": { 40 | "1": { 41 | "name": "string.quoted.multi.python" 42 | }, 43 | "2": { 44 | "name": "punctuation.definition.string.end.python" 45 | } 46 | }, 47 | "patterns": [ 48 | { 49 | "include": "source.graphql" 50 | } 51 | ] 52 | } 53 | ] 54 | } 55 | ], 56 | "scopeName": "inline.graphql.python" 57 | } 58 | -------------------------------------------------------------------------------- /syntaxes/graphql.rb.json: -------------------------------------------------------------------------------- 1 | { 2 | "fileTypes": ["rb"], 3 | "injectionSelector": "L:source -string -comment", 4 | "patterns": [ 5 | { 6 | "contentName": "meta.embedded.block.graphql", 7 | "begin": "(?><<[-~](['\"`]?)((?:[_\\w]+_|)GRAPHQL)\\b\\1)", 8 | "beginCaptures": { 9 | "0": { 10 | "name": "punctuation.definition.string.begin.ruby" 11 | } 12 | }, 13 | "end": "\\s*\\2$\\n?", 14 | "endCaptures": { 15 | "0": { 16 | "name": "punctuation.definition.string.end.ruby" 17 | } 18 | }, 19 | "patterns": [{ "include": "source.graphql" }] 20 | } 21 | ], 22 | "scopeName": "inline.graphql.ruby" 23 | } 24 | -------------------------------------------------------------------------------- /syntaxes/graphql.re.json: -------------------------------------------------------------------------------- 1 | { 2 | "fileTypes": ["re"], 3 | "injectionSelector": "L:source -string -comment", 4 | "patterns": [ 5 | { 6 | "contentName": "meta.embedded.block.graphql", 7 | "begin": "(\\[%(graphql|relay\\.([a-zA-Z]*)))s*$", 8 | "end": "(?<=])", 9 | "patterns": [ 10 | { 11 | "begin": "^\\s*({\\|)$", 12 | "end": "^\\s*(\\|})", 13 | "patterns": [{ "include": "source.graphql" }] 14 | } 15 | ] 16 | } 17 | ], 18 | "scopeName": "inline.graphql.reason" 19 | } 20 | -------------------------------------------------------------------------------- /syntaxes/publish.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -x 3 | 4 | if ! git diff --cached --exit-code; then 5 | echo "There are uncommitted changes. Please commit or stash them before running this script." 6 | exit 1 7 | fi 8 | 9 | CURRENT=$(git branch --show-current) 10 | CURRENT_HASH="ba347def950c46bc84971ae4aa47ab7622b2bbf6" #$(git rev-parse HEAD) 11 | 12 | git remote add --no-tags publish-docs git@github.com:apollographql/docs-rewrite -t main || true 13 | #git fetch publish-docs --depth 1 14 | git switch -C publish-docs/$CURRENT_HASH publish-docs/main 15 | 16 | update_file(){ 17 | 18 | if ! diff -q <(jq . <(git show $CURRENT_HASH:$1)) <(jq '.|del(._source)' < $2); then 19 | echo "connectors.mapping.json has changed, updating..." 20 | jq '{"_source":"https://github.com/apollographql/vscode-graphql/blob/'${CURRENT_HASH}'/'$1'"} + .' <(git show $CURRENT_HASH:$1) > $2 21 | git add $2 22 | else 23 | echo "connectors.mapping.json is up to date." 24 | fi 25 | } 26 | 27 | update_file syntaxes/connectors.mapping.json src/code-highlighting/grammars/connectors.mapping.json 28 | 29 | git diff --cached --shortstat 30 | update_file syntaxes/graphql.connectors.json src/code-highlighting/grammars/graphql.connectors.json 31 | update_file syntaxes/graphql.json src/code-highlighting/grammars/graphql.json 32 | 33 | git diff --cached --shortstat 34 | 35 | if ! git diff --cached --exit-code; then 36 | git commit -m "Update Syntax Highlighting\n source: https://github.com/apollographql/vscode-graphql/blob/${CURRENT_HASH}" 37 | git push -u publish-docs publish-docs/$CURRENT_HASH:sync-vscode-graphql/$CURRENT_HASH 38 | gh -R apollographql/docs-rewrite pr create --head sync-vscode-graphql/$CURRENT_HASH --title "Update Syntax Highlighting" --body "This PR updates the syntax highlighting files to match the latest changes in the vscode-graphql repository." 39 | else 40 | echo "No changes to commit." 41 | fi 42 | 43 | git switch $CURRENT 44 | -------------------------------------------------------------------------------- /syntaxes/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "esnext", 4 | "module": "esnext", 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "exclude": [ 4 | "./lib", 5 | "**/__tests__/*", 6 | "**/__e2e__/*", 7 | "**/__mocks__/*", 8 | "./sampleWorkspace", 9 | "jest.config.ts" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "rootDir": "./src", 4 | "outDir": "./lib", 5 | "target": "es2020", 6 | "module": "commonjs", 7 | "moduleResolution": "node", 8 | "esModuleInterop": true, 9 | "sourceMap": true, 10 | "declaration": true, 11 | "declarationMap": true, 12 | "removeComments": true, 13 | "allowJs": true, 14 | "strict": true, 15 | "noImplicitAny": true, 16 | "noImplicitReturns": true, 17 | "noFallthroughCasesInSwitch": true, 18 | "noUnusedParameters": false, 19 | "noUnusedLocals": false, 20 | "forceConsistentCasingInFileNames": true, 21 | "lib": ["es2020", "esnext.asynciterable"], 22 | "types": ["node", "jest"], 23 | "baseUrl": "." 24 | }, 25 | "include": ["./src"], 26 | "exclude": ["./lib", "jest.config.ts", "./sampleWorkspace"] 27 | } 28 | --------------------------------------------------------------------------------