Skip to content

About

A chrome extensions to retrieve the graphQL query from an Apollo GQL client using persisted queries

Topics

Resources

Contributing

Stars

2 stars

Watchers

1 watching

Forks

Latest commit

 

History

69 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

GraphQL Debugger — Chrome DevTools extension for debugging GraphQL

GraphQL Debugger (formerly APQ Debugger) works on network traffic, so it works with any GraphQL client on any site. It reveals the full GraphQL operation behind Apollo Client's Automatic Persisted Queries (APQ) hashes and visualizes the fallback flow in Chrome DevTools. → Install from Chrome Web Store

Features

  • Network Interception: Intercept and modify GraphQL requests in real-time
  • Request Breakpoints: Pause a request by operation name (or the next one), edit its query, variables and headers, then resume or fail it
  • Pattern Matching: Use URL patterns to target specific GraphQL endpoints
  • DevTools Integration: Seamless integration with Chrome DevTools
  • APQ Fallback Visualization: See both the hash-only and full-query phases of APQ requests
  • Request History: Browse, filter, and inspect intercepted requests with syntax highlighting
  • Passive Mode: Resolve APQ hashes from a persisted hash registry without modifying any traffic
  • Schema Explorer: Auto-detect the GraphQL endpoint and browse its introspected schema
  • Copy as cURL: Replay any captured request from Bash or PowerShell, including captured request headers

Installation

  1. Clone this repository
  2. Run npm install and npm run build to produce the extension_build/ folder
  3. Open Chrome and go to chrome://extensions/
  4. Enable "Developer mode"
  5. Click "Load unpacked" and select the extension_build/ folder
  6. Open DevTools and look for the "GraphQL Debugger" panel

Usage

  1. Navigate to the target page with Apollo Client
  2. Open Chrome DevTools and go to the "GraphQL Debugger" panel
  3. Add URL patterns to match GraphQL endpoints (e.g., *graphql*, */api/*)
  4. Click "Start Debugging" to begin interception
  5. Intercepted requests will trigger twice:
    • First: Failing due to PersistedQueryNotFound
    • Second: Containing the full GraphQL query

Breakpoints

Breakpoints hold a matching request in the service worker before it is sent; only the request is held, the page keeps running.

  1. Start interception on the Requests tab, then open the Breakpoints tab
  2. Add an operation name (e.g. GetCart) and turn on Debug mode, or press Pause on next request to catch whatever is sent next
  3. When a request pauses, edit its Query, Variables or Headers, then Resume this (or Resume all, F8), or Fail request to make the page's fetch fail
  4. Invalid JSON in Variables or Headers blocks the resume with an inline error. An edited query gets its persisted-query hash recomputed

In active mode a hash-only request is never paused (it is still swapped as usual); its full-query retry is. In passive mode hash-only requests pause too. Requests are only held while the panel is open: closing it, navigating, closing the tab or stopping interception sends every held request on unmodified.

File Structure

apq-debugger/
├── frontend/
│   ├── devtools.html              # Main DevTools panel HTML
│   ├── css/                       # Kora design system layer
│   │   ├── tokens.css             # Color/type/spacing tokens (light-dark() theming)
│   │   ├── theme-dark.css         # Dark-mode gates (explicit + system preference)
│   │   ├── density.css            # Comfortable/Compact density scales
│   │   └── components.css         # Panel components in the Kora idiom
│   └── fonts/                     # Bundled woff2 (Italiana, Albert Sans,
│                                  # Spline Sans Mono — all SIL OFL 1.1)
├── js/
│   ├── shared/                    # Constants & logger shared by both bundles
│   ├── sw/                        # Service worker modules
│   │   ├── index.js               # Entry point – event wiring
│   │   ├── chrome-api.js          # Promise wrappers for Chrome APIs
│   │   ├── debugger-manager.js    # Attach/detach/restore lifecycle
│   │   ├── interceptor.js         # Fetch.requestPaused handler
│   │   ├── breakpoints.js         # Breakpoint list, debug mode, pause decision
│   │   ├── pause-queue.js         # Held requests: hold, resume, fail, release
│   │   ├── resume-body.js         # Build the resumed request from panel edits
│   │   ├── panel-presence.js      # Which tabs have a panel connected (ports)
│   │   ├── messaging.js           # onMessage router & action toggle
│   │   ├── storage.js             # chrome.storage.local helpers
│   │   ├── hash.js                # SHA-256 digest utility
│   │   ├── hash-registry.js       # Persisted hash → query registry (passive mode)
│   │   ├── endpoint-tracker.js    # GraphQL endpoints observed per tab
│   │   └── schema-loader.js       # Endpoint auto-detection & introspection
│   ├── ui/                        # DevTools panel modules
│   │   ├── index.js               # Entry point – panel creation
│   │   ├── state.js               # Shared reactive state
│   │   ├── dom-helpers.js         # DOM query & escape utilities
│   │   ├── patterns.js            # URL pattern CRUD & storage sync
│   │   ├── request-list.js        # Request list rendering & filtering
│   │   ├── request-detail.js      # Detail panel & copy-to-clipboard
│   │   ├── curl-copy.js           # Copy-as-cURL generators & modal
│   │   ├── status.js              # Status badge & banner management
│   │   ├── debugger-controls.js   # Start/stop button orchestration
│   │   ├── registry-controls.js   # Hash registry & passive mode controls
│   │   ├── schema-controls.js     # Schema loading controls & progress
│   │   ├── schema-viewer.js       # Introspected schema explorer
│   │   ├── tabs.js                # Requests / Schema / Breakpoints tab switching
│   │   ├── panel-port.js          # Port telling the SW this panel is open
│   │   ├── breakpoints-view.js    # Breakpoints tab: toolbar, paused queue, list
│   │   ├── paused-editor.js       # Edit, resume or fail a paused request
│   │   ├── settings.js            # Panel settings
│   │   ├── toolbar.js             # Toolbar actions
│   │   ├── keyboard.js            # Keyboard navigation
│   │   ├── layout.js              # Panel layout management
│   │   └── resize.js              # Resizable panel dividers
├── scripts/
│   ├── sync-version.js            # Sync package.json → manifest.json version
│   └── package-extension.js       # Zip extension_build/ for Web Store upload
├── tests/
│   ├── unit/                      # Jest unit tests
│   └── e2e/                       # Playwright end-to-end tests
├── icons/                         # Extension icons (16/32/48/128 px)
├── store/                         # Chrome Web Store assets
├── .github/workflows/             # CI/CD (lint, test, build, release)
├── manifest.json                  # Chrome extension manifest (MV3)
├── package.json                   # Node.js project metadata
├── build-enhanced.js              # esbuild-powered build script
└── README.md                      # This file

Development

Quick Start

  1. Install dependencies:

    npm install
  2. Build the extension:

    npm run build
  3. Watch mode for development:

    npm run watch
  4. Load the extension:

    • Go to chrome://extensions/ and enable Developer mode
    • Click "Load unpacked" and select the extension_build/ folder

Available Scripts

Script Description
npm run build Bundle & minify JS/CSS into extension_build/
npm run build:dev Development build with source maps
npm run watch Watch mode — rebuild on file changes
npm test Run unit tests (Jest)
npm run test:e2e Run end-to-end tests (Playwright)
npm run lint Lint JS with ESLint
npm run lint:fix Auto-fix lint issues
npm run format Format code with Prettier
npm run package Zip extension_build/ for Chrome Web Store
npm run release Build + package in one step

Releasing a New Version

# Bump version (auto-syncs manifest.json and creates a git tag)
npm version patch   # or minor / major

# Push the tag to trigger the release workflow
git push --follow-tags

The GitHub Actions release workflow will automatically build, test, and create a GitHub Release with the .zip artifact.

Technical Details

How It Works

  1. Pattern Matching: Uses the Chrome Debugger API's Fetch.requestPaused event to intercept requests matching user-specified URL patterns
  2. Hash Contamination: Replaces the SHA-256 hash in APQ-only requests with a bogus value, forcing Apollo Client to retry with the full query
  3. Query Capture: Captures the full GraphQL query from the retry request and sends it to the DevTools panel
  4. Real-time Display: The DevTools panel shows intercepted requests with filtering, syntax highlighting, and one-click copy

Architecture

  • Service Worker (js/sw/): Background process handling network interception via the Chrome Debugger API
  • DevTools Panel (js/ui/): User interface for configuration and live request monitoring
  • Message Passing: Bidirectional communication between the panel and service worker via chrome.runtime.sendMessage, plus a long-lived port per open panel so requests are only held while a panel is connected
  • Persistent State: URL patterns and attached-tab state are persisted in chrome.storage.local to survive service worker restarts

Privacy Note

The Copy as cURL feature includes the captured request headers — which may contain cookies and authorization tokens — in the generated command so the request can be replayed as-is. This data never leaves your browser; it is only written to your clipboard when you click Copy.

Your GraphQL traffic (URLs, queries, variables, headers, hashes, schemas) never leaves your browser. Official builds can optionally send anonymous feature-usage counts (which features are used, extension and browser version, OS, UI language) to Google Analytics, but only if you opt in; nothing is sent until you do, and you can switch it off any time in the panel settings, which also deletes the random IDs. Builds from source have no analytics configured. See the privacy policy.

Contributing

See CONTRIBUTING.md for development setup, architecture details, and contribution guidelines.

License

This project is licensed under the Apache License 2.0 — see the LICENSE file for details.

About

A chrome extensions to retrieve the graphQL query from an Apollo GQL client using persisted queries

Topics

Resources

Contributing

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages