Full Code of dstotijn/hetty for AI

main 52c83a198927 cached
161 files
688.4 KB
198.7k tokens
1051 symbols
1 requests
Download .txt
Showing preview only (734K chars total). Download the full file or copy to clipboard to get everything.
Repository: dstotijn/hetty
Branch: main
Commit: 52c83a198927
Files: 161
Total size: 688.4 KB

Directory structure:
gitextract_7r6v1eh1/

├── .dockerignore
├── .github/
│   ├── FUNDING.yml
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_report.md
│   │   ├── config.yml
│   │   └── feature_request.md
│   └── workflows/
│       ├── build-test.yml
│       └── lint.yml
├── .gitignore
├── .golangci.yml
├── .goreleaser.yml
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── Dockerfile
├── LICENSE
├── Makefile
├── README.md
├── admin/
│   ├── .eslintrc.json
│   ├── .gitignore
│   ├── .prettierignore
│   ├── .prettierrc.json
│   ├── gqlcodegen.yml
│   ├── next-env.d.ts
│   ├── next.config.js
│   ├── package.json
│   ├── public/
│   │   ├── site.webmanifest
│   │   └── style.css
│   ├── src/
│   │   ├── features/
│   │   │   ├── Layout.tsx
│   │   │   ├── intercept/
│   │   │   │   ├── components/
│   │   │   │   │   ├── EditRequest.tsx
│   │   │   │   │   ├── Intercept.tsx
│   │   │   │   │   └── Requests.tsx
│   │   │   │   └── graphql/
│   │   │   │       ├── cancelRequest.graphql
│   │   │   │       ├── cancelResponse.graphql
│   │   │   │       ├── interceptedRequest.graphql
│   │   │   │       ├── modifyRequest.graphql
│   │   │   │       └── modifyResponse.graphql
│   │   │   ├── projects/
│   │   │   │   ├── components/
│   │   │   │   │   ├── NewProject.tsx
│   │   │   │   │   └── ProjectList.tsx
│   │   │   │   ├── graphql/
│   │   │   │   │   ├── activeProject.graphql
│   │   │   │   │   ├── closeProject.graphql
│   │   │   │   │   ├── createProject.graphql
│   │   │   │   │   ├── deleteProject.graphql
│   │   │   │   │   ├── openProject.graphql
│   │   │   │   │   └── projects.graphql
│   │   │   │   └── hooks/
│   │   │   │       └── useOpenProjectMutation.ts
│   │   │   ├── reqlog/
│   │   │   │   ├── components/
│   │   │   │   │   ├── Actions.tsx
│   │   │   │   │   ├── LogDetail.tsx
│   │   │   │   │   ├── RequestDetail.tsx
│   │   │   │   │   ├── RequestLogs.tsx
│   │   │   │   │   └── Search.tsx
│   │   │   │   ├── graphql/
│   │   │   │   │   ├── clearHttpRequestLog.graphql
│   │   │   │   │   ├── httpRequestLog.graphql
│   │   │   │   │   ├── httpRequestLogFilter.graphql
│   │   │   │   │   ├── httpRequestLogs.graphql
│   │   │   │   │   └── setHttpRequestLogFilter.graphql
│   │   │   │   └── index.ts
│   │   │   ├── scope/
│   │   │   │   ├── components/
│   │   │   │   │   ├── AddRule.tsx
│   │   │   │   │   ├── RuleListItem.tsx
│   │   │   │   │   └── Rules.tsx
│   │   │   │   └── graphql/
│   │   │   │       ├── scope.graphql
│   │   │   │       └── setScope.graphql
│   │   │   ├── sender/
│   │   │   │   ├── components/
│   │   │   │   │   ├── EditRequest.tsx
│   │   │   │   │   ├── History.tsx
│   │   │   │   │   └── Sender.tsx
│   │   │   │   ├── graphql/
│   │   │   │   │   ├── createOrUpdateRequest.graphql
│   │   │   │   │   ├── createSenderRequestFromRequestLog.graphql
│   │   │   │   │   ├── sendRequest.graphql
│   │   │   │   │   ├── senderRequest.graphql
│   │   │   │   │   └── senderRequests.graphql
│   │   │   │   └── index.ts
│   │   │   └── settings/
│   │   │       ├── components/
│   │   │       │   └── Settings.tsx
│   │   │       └── graphql/
│   │   │           └── updateInterceptSettings.graphql
│   │   ├── lib/
│   │   │   ├── ActiveProjectContext.tsx
│   │   │   ├── InterceptedRequestsContext.tsx
│   │   │   ├── components/
│   │   │   │   ├── ConfirmationDialog.tsx
│   │   │   │   ├── Editor.tsx
│   │   │   │   ├── HttpStatusIcon.tsx
│   │   │   │   ├── KeyValuePair.tsx
│   │   │   │   ├── Link.tsx
│   │   │   │   ├── RequestTabs.tsx
│   │   │   │   ├── RequestsTable.tsx
│   │   │   │   ├── Response.tsx
│   │   │   │   ├── ResponseStatus.tsx
│   │   │   │   ├── ResponseTabs.tsx
│   │   │   │   ├── SplitPane.tsx
│   │   │   │   ├── UrlBar.tsx
│   │   │   │   └── useContextMenu.tsx
│   │   │   ├── graphql/
│   │   │   │   ├── generated.tsx
│   │   │   │   ├── interceptedRequests.graphql
│   │   │   │   ├── omitTypename.ts
│   │   │   │   └── useApollo.ts
│   │   │   ├── mui/
│   │   │   │   ├── createEmotionCache.ts
│   │   │   │   └── theme.ts
│   │   │   ├── queryParamsFromURL.tsx
│   │   │   ├── updateKeyPairItem.ts
│   │   │   └── updateURLQueryParams.ts
│   │   ├── pages/
│   │   │   ├── _app.tsx
│   │   │   ├── _document.tsx
│   │   │   ├── index.tsx
│   │   │   ├── projects/
│   │   │   │   └── index.tsx
│   │   │   ├── proxy/
│   │   │   │   ├── index.tsx
│   │   │   │   ├── intercept/
│   │   │   │   │   └── index.tsx
│   │   │   │   └── logs/
│   │   │   │       └── index.tsx
│   │   │   ├── scope/
│   │   │   │   └── index.tsx
│   │   │   ├── sender/
│   │   │   │   └── index.tsx
│   │   │   └── settings/
│   │   │       └── index.tsx
│   │   └── styles.css
│   └── tsconfig.json
├── cmd/
│   └── hetty/
│       ├── cert.go
│       ├── config.go
│       ├── hetty.go
│       └── main.go
├── go.mod
├── go.sum
├── gqlgen.yml
├── pkg/
│   ├── api/
│   │   ├── generated.go
│   │   ├── http.go
│   │   ├── models.go
│   │   ├── models_gen.go
│   │   ├── resolvers.go
│   │   └── schema.graphql
│   ├── chrome/
│   │   └── chrome.go
│   ├── db/
│   │   └── bolt/
│   │       ├── bolt.go
│   │       ├── logger.go
│   │       ├── proj.go
│   │       ├── proj_test.go
│   │       ├── reqlog.go
│   │       ├── reqlog_test.go
│   │       ├── sender.go
│   │       └── sender_test.go
│   ├── filter/
│   │   ├── ast.go
│   │   ├── ast_test.go
│   │   ├── http.go
│   │   ├── lexer.go
│   │   ├── lexer_test.go
│   │   ├── parser.go
│   │   └── parser_test.go
│   ├── log/
│   │   └── log.go
│   ├── proj/
│   │   ├── proj.go
│   │   └── repo.go
│   ├── proxy/
│   │   ├── cert.go
│   │   ├── gzip.go
│   │   ├── intercept/
│   │   │   ├── filter.go
│   │   │   ├── intercept.go
│   │   │   ├── intercept_test.go
│   │   │   └── settings.go
│   │   ├── modify.go
│   │   ├── net.go
│   │   └── proxy.go
│   ├── reqlog/
│   │   ├── repo.go
│   │   ├── reqlog.go
│   │   ├── reqlog_test.go
│   │   ├── search.go
│   │   └── search_test.go
│   ├── scope/
│   │   └── scope.go
│   └── sender/
│       ├── repo.go
│       ├── search.go
│       ├── search_test.go
│       ├── sender.go
│       ├── sender_test.go
│       └── transport.go
└── tools.go

================================================
FILE CONTENTS
================================================

================================================
FILE: .dockerignore
================================================
/admin/.env
/admin/.next
/admin/dist
/admin/node_modules
/dist
/docs
/hetty
/cmd/hetty/admin

================================================
FILE: .github/FUNDING.yml
================================================
github: dstotijn
patreon: dstotijn
custom: "https://www.paypal.com/paypalme/dstotijn"


================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.md
================================================
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''

---

**Describe the bug**
A clear and concise description of what the bug is.

**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error

**Expected behavior**
A clear and concise description of what you expected to happen.

**Screenshots**
If applicable, add screenshots to help explain your problem.

**Desktop (please complete the following information):**
 - OS: [e.g. iOS]
 - Browser [e.g. chrome, safari]
 - Version [e.g. 22]

**Smartphone (please complete the following information):**
 - Device: [e.g. iPhone6]
 - OS: [e.g. iOS8.1]
 - Browser [e.g. stock browser, safari]
 - Version [e.g. 22]

**Additional context**
Add any other context about the problem here.


================================================
FILE: .github/ISSUE_TEMPLATE/config.yml
================================================
blank_issues_enabled: false
contact_links:
  - name: Ask a question
    url: https://github.com/dstotijn/hetty/discussions
    about: Ask questions and discuss with other community members


================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.md
================================================
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''

---

**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

**Describe the solution you'd like**
A clear and concise description of what you want to happen.

**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.

**Additional context**
Add any other context or screenshots about the feature request here.


================================================
FILE: .github/workflows/build-test.yml
================================================
name: Build and Test
on: [push, pull_request]
jobs:
  build:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        go: ["1.23", "1.22", "1.21"]
    name: Go ${{ matrix.go }} - Build
    steps:
      - uses: actions/checkout@v2
      - uses: actions/setup-go@v2
        with:
          go-version: ${{ matrix.go }}
      - uses: actions/setup-node@v2
        with:
          node-version: "16"
      - uses: actions/cache@v2
        with:
          path: |
            ~/.cache/go-build
            ~/go/pkg/mod
          key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
          restore-keys: |
            ${{ runner.os }}-go-
      - uses: actions/cache@v2
        with:
          path: ${{ github.workspace }}/admin/.next/cache
          key: ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('**.[jt]s', '**.[jt]sx') }}
          restore-keys: |
            ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}-
      - run: make build
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        go: ["1.23", "1.22", "1.21"]
    name: Go ${{ matrix.go }} - Test
    steps:
      - uses: actions/checkout@v2
      - uses: actions/setup-go@v2
        with:
          go-version: ${{ matrix.go }}
      - uses: actions/cache@v2
        with:
          path: |
            ~/.cache/go-build
            ~/go/pkg/mod
          key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
          restore-keys: |
            ${{ runner.os }}-go-
      - run: go test ./pkg/...


================================================
FILE: .github/workflows/lint.yml
================================================
name: Lint
on: [push, pull_request]
defaults:
  run:
    working-directory: ./admin
jobs:
  lint-admin:
    runs-on: ubuntu-latest
    name: Admin (Next.js)
    steps:
      - uses: actions/checkout@v2
      - uses: actions/setup-node@v2
        with:
          node-version: "16"
      - run: yarn install
      - run: yarn run lint

================================================
FILE: .gitignore
================================================
*.vscode
/dist
/hetty
/cmd/hetty/admin
*.pem
*.test

================================================
FILE: .golangci.yml
================================================
linters:
  presets:
    - bugs
    - comment
    - error
    - format
    - import
    - metalinter
    - module
    - performance
    - style
    - test
    - unused
  disable:
    - dupl
    - exhaustive
    - exhaustivestruct
    - gochecknoglobals
    - gochecknoinits
    - godox
    - goerr113
    - gomnd
    - interfacer
    - maligned
    - nilnil
    - nlreturn
    - scopelint 
    - testpackage
    - varnamelen
    - wrapcheck

linters-settings:
  gci:
    local-prefixes: github.com/dstotijn/hetty
  godot:
    capital: true
  ireturn:
    allow: "error,empty,anon,stdlib,.*(or|er)$,github.com/99designs/gqlgen/graphql.Marshaler,github.com/dstotijn/hetty/pkg/api.QueryResolver,github.com/dstotijn/hetty/pkg/filter.Expression"
    
issues:
  exclude-rules:
    - linters:
      - gosec
      # Ignore SHA1 usage.
      text: "G(401|505):"
    - linters:
      - wsl
      # Ignore cuddled defer statements.
      text: "only one cuddle assignment allowed before defer statement"
    - linters:
      - nlreturn
      # Ignore `break` without leading blank line.
      text: "break with no blank line before"

================================================
FILE: .goreleaser.yml
================================================
before:
  hooks:
    - make clean
    - sh -c "NEXT_PUBLIC_VERSION={{ .Version}} make build-admin"
    - go mod tidy

builds:
  - env:
      - CGO_ENABLED=0
    main: ./cmd/hetty
    ldflags:
      - -s -w -X main.version={{.Version}}
    goos:
      - linux
      - windows
      - darwin
    goarch:
      - amd64
      - arm64

archives:
  - replacements:
      darwin: macOS
      linux: Linux
      windows: Windows
      amd64: x86_64
    format_overrides:
      - goos: windows
        format: zip

brews:
  - tap:
      owner: hettysoft
      name: homebrew-tap
    folder: Formula
    homepage:  https://hetty.xyz
    description: An HTTP toolkit for security research.
    license: MIT
    commit_author:
      name: David Stotijn
      email: dstotijn@gmail.com
    test: |
      system "#{bin}/hetty -v"

snapcrafts:
  - publish: true
    summary: An HTTP toolkit for security research.
    description: |
      Hetty is an HTTP toolkit for security research. It aims to become an open
      source alternative to commercial software like Burp Suite Pro, with
      powerful features tailored to the needs of the infosec and bug bounty
      community.
    grade: stable
    confinement: strict
    license: MIT
    apps:
      hetty:
        command: hetty
        plugs: ["network", "network-bind"]

scoop:
  bucket:
    owner: hettysoft
    name: scoop-bucket
  commit_author:
    name: David Stotijn
    email: dstotijn@gmail.com
  homepage:  https://hetty.xyz
  description: An HTTP toolkit for security research.
  license: MIT

dockers:
  - extra_files:
    - go.mod
    - go.sum
    - pkg
    - cmd
    - admin
    image_templates:
    - "ghcr.io/dstotijn/hetty:{{ .Version }}"
    - "ghcr.io/dstotijn/hetty:{{ .Major }}"
    - "ghcr.io/dstotijn/hetty:{{ .Major }}.{{ .Minor }}"
    - "ghcr.io/dstotijn/hetty:latest"
    - "dstotijn/hetty:{{ .Version }}"
    - "dstotijn/hetty:{{ .Major }}"
    - "dstotijn/hetty:{{ .Major }}.{{ .Minor }}"
    - "dstotijn/hetty:latest"
    build_flag_templates:
    - "--pull"
    - "--label=org.opencontainers.image.created={{.Date}}"
    - "--label=org.opencontainers.image.title={{.ProjectName}}"
    - "--label=org.opencontainers.image.revision={{.FullCommit}}"
    - "--label=org.opencontainers.image.version={{.Version}}"
    - "--label=org.opencontainers.image.source=https://github.com/dstotijn/hetty"
    - "--build-arg=HETTY_VERSION={{.Version}}"

checksum:
  name_template: "checksums.txt"

snapshot:
  name_template: "{{ incpatch .Version }}-next"

changelog:
  sort: asc
  filters:
    exclude:
      - "^docs:"
      - "^test:"

================================================
FILE: CODE_OF_CONDUCT.md
================================================
# Contributor Covenant Code of Conduct

## Our Pledge

In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, sex characteristics, gender identity and expression,
level of experience, education, socio-economic status, nationality, personal
appearance, race, religion, or sexual identity and orientation.

## Our Standards

Examples of behavior that contributes to creating a positive environment
include:

* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members

Examples of unacceptable behavior by participants include:

* The use of sexualized language or imagery and unwelcome sexual attention or
 advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
 address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
 professional setting

## Our Responsibilities

Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.

Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.

## Scope

This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.

## Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at dstotijn@gmail.com. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.

Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.

## Attribution

This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html

[homepage]: https://www.contributor-covenant.org

For answers to common questions about this code of conduct, see
https://www.contributor-covenant.org/faq


================================================
FILE: CONTRIBUTING.md
================================================
# Contribution Guidelines

Thank you for taking an interest in Hetty! If you want to contribute to the
project, please read the guidelines below to ensure a smooth develop experience.

## Code of conduct

Please first read the [code of conduct](CODE_OF_CONDUCT.md), and abide to it
whenever you interact with the community.

## Issues

Use [issues](https://github.com/dstotijn/hetty/issues) for reporting bugs,
adding feature requests and giving context to PRs you submit. Please use [labels](https://github.com/dstotijn/hetty/labels)
in favor of category prefixes in issue titles. To keep the issue tracker
focused on development, use [discussions](https://github.com/dstotijn/hetty/discussions)
for usage questions and non-code related discourse.

Before submitting new feature requests, check out the Kanban board for the
status of on-going work. There might already be a card/issue.

## Pull requests

Before submitting a pull request that introduces a new feature or significantly
changes the behavior of Hetty, please consider first using [discussions](https://github.com/dstotijn/hetty/discussions)
or commenting on a relevant existing issue to share what you have in mind.
Because the project is in an early stage, this is especially important; there
are still a lot of major design decisions to be made. Until the foundation has
solidified, design and implementation leading up to the first milestone (v1.0)
is highly in flux, and your work might not align/be applicable for what the
maintainers have envisioned.

## Development

_Todo: Write steps for setting up local development environment._


================================================
FILE: Dockerfile
================================================
ARG GO_VERSION=1.17
ARG NODE_VERSION=16.13
ARG ALPINE_VERSION=3.15

FROM node:${NODE_VERSION}-alpine AS node-builder
WORKDIR /app
COPY admin/package.json admin/yarn.lock ./
RUN yarn install --frozen-lockfile
COPY admin/ .
ENV NEXT_TELEMETRY_DISABLED=1
RUN yarn run export

FROM golang:${GO_VERSION}-alpine AS go-builder
ARG HETTY_VERSION=0.0.0
ENV CGO_ENABLED=0
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY cmd ./cmd
COPY pkg ./pkg
COPY --from=node-builder /app/dist ./cmd/hetty/admin
RUN go build -ldflags="-s -w -X main.version=${HETTY_VERSION}" ./cmd/hetty

FROM alpine:${ALPINE_VERSION}
WORKDIR /app
COPY --from=go-builder /app/hetty .

ENTRYPOINT ["./hetty"]

EXPOSE 8080

================================================
FILE: LICENSE
================================================
MIT License

Copyright (c) 2021 David Stotijn

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: Makefile
================================================
export CGO_ENABLED = 0
export NEXT_TELEMETRY_DISABLED = 1

.PHONY: build
build: build-admin
	go build ./cmd/hetty

.PHONY: build-admin
build-admin:
	cd admin && \
	yarn install --frozen-lockfile && \
	yarn run export && \
    mv dist ../cmd/hetty/admin

.PHONY: clean
clean:
	rm -f hetty
	rm -rf ./cmd/hetty/admin
	rm -rf ./admin/dist
	rm -rf ./admin/.next

================================================
FILE: README.md
================================================
<img src="https://user-images.githubusercontent.com/983924/156430531-6193e187-7400-436b-81c6-f86862783ea5.svg#gh-light-mode-only" width="240"/>
<img src="https://user-images.githubusercontent.com/983924/156430660-9d5bd555-dcfd-47e2-ba70-54294c20c1b4.svg#gh-dark-mode-only" width="240"/>

[![Latest GitHub release](https://img.shields.io/github/v/release/dstotijn/hetty?color=25ae8f)](https://github.com/dstotijn/hetty/releases/latest)
[![Build Status](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Factions-badge.atrox.dev%2Fdstotijn%2Fhetty%2Fbadge%3Fref%3Dmain&label=build&color=24ae8f)](https://github.com/dstotijn/hetty/actions/workflows/build-test.yml)
![GitHub download count](https://img.shields.io/github/downloads/dstotijn/hetty/total?color=25ae8f)
[![GitHub](https://img.shields.io/github/license/dstotijn/hetty?color=25ae8f)](https://github.com/dstotijn/hetty/blob/master/LICENSE)
[![Documentation](https://img.shields.io/badge/hetty-docs-25ae8f)](https://hetty.xyz/)

**Hetty** is an HTTP toolkit for security research. It aims to become an open
source alternative to commercial software like Burp Suite Pro, with powerful
features tailored to the needs of the infosec and bug bounty community.

<img src="https://hetty.xyz/img/hero.png" width="907" alt="Hetty proxy logs (screenshot)" />

## Features

- Machine-in-the-middle (MITM) HTTP proxy, with logs and advanced search
- HTTP client for manually creating/editing requests, and replay proxied requests
- Intercept requests and responses for manual review (edit, send/receive, cancel)
- Scope support, to help keep work organized
- Easy-to-use web based admin interface
- Project based database storage, to help keep work organized

👷‍♂️ Hetty is under active development. Check the <a
href="https://github.com/dstotijn/hetty/projects/1">backlog</a> for the current
status.

📣 Are you pen testing professionaly in a team? I would love to hear your
thoughts on tooling via [this 5 minute
survey](https://forms.gle/36jtgNc3TJ2imi5A8). Thank you!

## Getting started

💡 The [Getting started](https://hetty.xyz/docs/getting-started) doc has more
detailed install and usage instructions.

### Installation

The quickest way to install and update Hetty is via a package manager:

#### macOS

```sh
brew install hettysoft/tap/hetty
```

#### Linux

```sh
sudo snap install hetty
```

#### Windows

```sh
scoop bucket add hettysoft https://github.com/hettysoft/scoop-bucket.git
scoop install hettysoft/hetty
```

#### Other

Alternatively, you can [download the latest release from
GitHub](https://github.com/dstotijn/hetty/releases/latest) for your OS and
architecture, and move the binary to a directory in your `$PATH`. If your OS is
not available for one of the package managers or not listed in the GitHub
releases, you can compile from source _(link coming soon)_.

#### Docker

Docker images are distributed via [GitHub's Container registry](https://github.com/dstotijn/hetty/pkgs/container/hetty)
and [Docker Hub](https://hub.docker.com/r/dstotijn/hetty). To run Hetty via with a volume for database and certificate
storage, and port 8080 forwarded:

```
docker run -v $HOME/.hetty:/root/.hetty -p 8080:8080 \
  ghcr.io/dstotijn/hetty:latest
```

### Usage

Once installed, start Hetty via:

```sh
hetty
```

💡 Read the [Getting started](https://hetty.xyz/docs/getting-started) doc for
more details.

To list all available options, run: `hetty --help`:

```
$ hetty --help

Usage:
    hetty [flags] [subcommand] [flags]

Runs an HTTP server with (MITM) proxy, GraphQL service, and a web based admin interface.

Options:
    --cert         Path to root CA certificate. Creates file if it doesn't exist. (Default: "~/.hetty/hetty_cert.pem")
    --key          Path to root CA private key. Creates file if it doesn't exist. (Default: "~/.hetty/hetty_key.pem")
    --db           Database file path. Creates file if it doesn't exist. (Default: "~/.hetty/hetty.db")
    --addr         TCP address for HTTP server to listen on, in the form \"host:port\". (Default: ":8080")
    --chrome       Launch Chrome with proxy settings applied and certificate errors ignored. (Default: false)
    --verbose      Enable verbose logging.
    --json         Encode logs as JSON, instead of pretty/human readable output.
    --version, -v  Output version.
    --help, -h     Output this usage text.

Subcommands:
    - cert  Certificate management

Run `hetty <subcommand> --help` for subcommand specific usage instructions.

Visit https://hetty.xyz to learn more about Hetty.
```

## Documentation

📖 [Read the docs](https://hetty.xyz/docs)

## Support

Use [issues](https://github.com/dstotijn/hetty/issues) for bug reports and
feature requests, and
[discussions](https://github.com/dstotijn/hetty/discussions) for questions and
troubleshooting.

## Community

💬 [Join the Hetty Discord server](https://discord.gg/3HVsj5pTFP)

## Contributing

Want to contribute? Great! Please check the [Contribution
Guidelines](CONTRIBUTING.md) for details.

## Acknowledgements

- Thanks to the [Hacker101 community on Discord](https://www.hacker101.com/discord)
  for the encouragement and early feedback.
- The font used in the logo and admin interface is [JetBrains
  Mono](https://www.jetbrains.com/lp/mono/).

## Sponsors

💖 Are you enjoying Hetty? You can [sponsor me](https://github.com/sponsors/dstotijn)!

## License

[MIT](LICENSE)

© 2019–2025 Hetty Software


================================================
FILE: admin/.eslintrc.json
================================================
{
  "root": true,
  "extends": ["next/core-web-vitals", "prettier", "plugin:@typescript-eslint/recommended", "plugin:import/typescript"],
  "plugins": ["prettier", "@typescript-eslint", "import"],
  "ignorePatterns": ["next*", "src/lib/graphql/generated.tsx"],
  "settings": {
    "import/parsers": {
      "@typescript-eslint/parser": [".ts", ".tsx"]
    },
    "import/resolver": {
      "typescript": {
        "alwaysTryTypes": true
      }
    }
  },
  "rules": {
    "prettier/prettier": ["error"],
    "@next/next/no-css-tags": "off",
    "no-unused-vars": "off",
    "@typescript-eslint/no-unused-vars": [
      "error",
      {
        "ignoreRestSiblings": true
      }
    ],

    "import/default": "off",

    "import/no-unresolved": "error",
    "import/named": "error",
    "import/namespace": "error",
    "import/export": "error",
    "import/no-deprecated": "error",
    "import/no-cycle": "error",

    "import/no-named-as-default": "warn",
    "import/no-named-as-default-member": "warn",
    "import/no-duplicates": "warn",
    "import/newline-after-import": "warn",
    "import/order": [
      "warn",
      {
        "alphabetize": { "order": "asc", "caseInsensitive": false },
        "newlines-between": "always",
        "groups": ["builtin", "external", "parent", "sibling", "index"]
      }
    ],
    "import/no-unused-modules": [
      "error",
      {
        "missingExports": true,
        "ignoreExports": ["./src/pages"]
      }
    ]
  }
}


================================================
FILE: admin/.gitignore
================================================
/node_modules
/.next
/dist

*.log*


================================================
FILE: admin/.prettierignore
================================================
/.next/
/out/
/build
/coverage


================================================
FILE: admin/.prettierrc.json
================================================
{
    "printWidth": 120
}


================================================
FILE: admin/gqlcodegen.yml
================================================
overwrite: true
schema: "../pkg/api/schema.graphql"
documents: "src/**/*.graphql"
generates:
  src/lib/graphql/generated.tsx:
    plugins:
      - "typescript"
      - "typescript-operations"
      - "typescript-react-apollo"


================================================
FILE: admin/next-env.d.ts
================================================
/// <reference types="next" />
/// <reference types="next/image-types/global" />

// NOTE: This file should not be edited
// see https://nextjs.org/docs/basic-features/typescript for more information.


================================================
FILE: admin/next.config.js
================================================
// @ts-check

/**
 * @type {import('next').NextConfig}
 **/
const nextConfig = {
  reactStrictMode: true,
  trailingSlash: true,
  async rewrites() {
    return [
      {
        source: "/api/:path/",
        destination: "http://localhost:8080/api/:path/",
      },
    ];
  },
};

module.exports = nextConfig;


================================================
FILE: admin/package.json
================================================
{
  "name": "hetty-admin",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint",
    "export": "next build && next export -o dist",
    "generate": "graphql-codegen --config gqlcodegen.yml"
  },
  "dependencies": {
    "@apollo/client": "^3.2.0",
    "@emotion/react": "^11.7.1",
    "@emotion/server": "^11.4.0",
    "@emotion/styled": "^11.6.0",
    "@monaco-editor/react": "^4.3.1",
    "@mui/icons-material": "^5.3.1",
    "@mui/lab": "^5.0.0-alpha.66",
    "@mui/material": "^5.3.1",
    "@mui/styles": "^5.4.2",
    "allotment": "^1.9.0",
    "deepmerge": "^4.2.2",
    "graphql": "^16.2.0",
    "lodash": "^4.17.21",
    "monaco-editor": "^0.31.1",
    "next": "^12.0.8",
    "next-fonts": "^1.0.3",
    "react": "^17.0.2",
    "react-dom": "^17.0.2",
    "react-split-pane": "^0.1.92"
  },
  "devDependencies": {
    "@babel/core": "^7.0.0",
    "@graphql-codegen/cli": "2.6.1",
    "@graphql-codegen/introspection": "2.1.1",
    "@graphql-codegen/typescript": "2.4.3",
    "@graphql-codegen/typescript-operations": "2.3.0",
    "@graphql-codegen/typescript-react-apollo": "3.2.6",
    "@types/lodash": "^4.14.178",
    "@types/node": "^17.0.12",
    "@types/react": "^17.0.38",
    "@typescript-eslint/eslint-plugin": "^5.12.0",
    "@typescript-eslint/parser": "^5.12.0",
    "eslint": "^8.7.0",
    "eslint-config-next": "12.0.8",
    "eslint-config-prettier": "^8.3.0",
    "eslint-import-resolver-typescript": "^2.5.0",
    "eslint-plugin-import": "^2.25.4",
    "eslint-plugin-prettier": "^4.0.0",
    "prettier": "^2.1.2",
    "typescript": "^4.0.3",
    "webpack": "^5.67.0"
  }
}


================================================
FILE: admin/public/site.webmanifest
================================================
{"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"}

================================================
FILE: admin/public/style.css
================================================
@font-face {
  font-family: "JetBrains Mono";
  src: url("https://cdn.jsdelivr.net/gh/JetBrains/JetBrainsMono/web/woff2/JetBrainsMono-Bold-Italic.woff2")
      format("woff2"),
    url("https://cdn.jsdelivr.net/gh/JetBrains/JetBrainsMono/web/woff/JetBrainsMono-Bold-Italic.woff")
      format("woff");
  font-weight: 700;
  font-style: italic;
  font-display: swap;
}

@font-face {
  font-family: "JetBrains Mono";
  src: url("https://cdn.jsdelivr.net/gh/JetBrains/JetBrainsMono/web/woff2/JetBrainsMono-Bold.woff2")
      format("woff2"),
    url("https://cdn.jsdelivr.net/gh/JetBrains/JetBrainsMono/web/woff/JetBrainsMono-Bold.woff")
      format("woff");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "JetBrains Mono";
  src: url("https://cdn.jsdelivr.net/gh/JetBrains/JetBrainsMono/web/woff2/JetBrainsMono-ExtraBold-Italic.woff2")
      format("woff2"),
    url("https://cdn.jsdelivr.net/gh/JetBrains/JetBrainsMono/web/woff/JetBrainsMono-ExtraBold-Italic.woff")
      format("woff");
  font-weight: 800;
  font-style: italic;
  font-display: swap;
}

@font-face {
  font-family: "JetBrains Mono";
  src: url("https://cdn.jsdelivr.net/gh/JetBrains/JetBrainsMono/web/woff2/JetBrainsMono-ExtraBold.woff2")
      format("woff2"),
    url("https://cdn.jsdelivr.net/gh/JetBrains/JetBrainsMono/web/woff/JetBrainsMono-ExtraBold.woff")
      format("woff");
  font-weight: 800;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "JetBrains Mono";
  src: url("https://cdn.jsdelivr.net/gh/JetBrains/JetBrainsMono/web/woff2/JetBrainsMono-Italic.woff2")
      format("woff2"),
    url("https://cdn.jsdelivr.net/gh/JetBrains/JetBrainsMono/web/woff/JetBrainsMono-Italic.woff")
      format("woff");
  font-weight: 400;
  font-style: italic;
  font-display: swap;
}

@font-face {
  font-family: "JetBrains Mono";
  src: url("https://cdn.jsdelivr.net/gh/JetBrains/JetBrainsMono/web/woff2/JetBrainsMono-Medium-Italic.woff2")
      format("woff2"),
    url("https://cdn.jsdelivr.net/gh/JetBrains/JetBrainsMono/web/woff/JetBrainsMono-Medium-Italic.woff")
      format("woff");
  font-weight: 500;
  font-style: italic;
  font-display: swap;
}

@font-face {
  font-family: "JetBrains Mono";
  src: url("https://cdn.jsdelivr.net/gh/JetBrains/JetBrainsMono/web/woff2/JetBrainsMono-Medium.woff2")
      format("woff2"),
    url("https://cdn.jsdelivr.net/gh/JetBrains/JetBrainsMono/web/woff/JetBrainsMono-Medium.woff")
      format("woff");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "JetBrains Mono";
  src: url("https://cdn.jsdelivr.net/gh/JetBrains/JetBrainsMono/web/woff2/JetBrainsMono-Regular.woff2")
      format("woff2"),
    url("https://cdn.jsdelivr.net/gh/JetBrains/JetBrainsMono/web/woff/JetBrainsMono-Regular.woff")
      format("woff");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

code {
  font-family: "JetBrains Mono", monospace;
}


================================================
FILE: admin/src/features/Layout.tsx
================================================
import AltRouteIcon from "@mui/icons-material/AltRoute";
import ChevronLeftIcon from "@mui/icons-material/ChevronLeft";
import ChevronRightIcon from "@mui/icons-material/ChevronRight";
import FolderIcon from "@mui/icons-material/Folder";
import FormatListBulletedIcon from "@mui/icons-material/FormatListBulleted";
import HomeIcon from "@mui/icons-material/Home";
import LocationSearchingIcon from "@mui/icons-material/LocationSearching";
import MenuIcon from "@mui/icons-material/Menu";
import SendIcon from "@mui/icons-material/Send";
import {
  Theme,
  useTheme,
  Toolbar,
  IconButton,
  Typography,
  Divider,
  List,
  Tooltip,
  styled,
  CSSObject,
  Box,
  ListItemText,
  Badge,
} from "@mui/material";
import MuiAppBar, { AppBarProps as MuiAppBarProps } from "@mui/material/AppBar";
import MuiDrawer from "@mui/material/Drawer";
import MuiListItemButton, { ListItemButtonProps } from "@mui/material/ListItemButton";
import MuiListItemIcon, { ListItemIconProps } from "@mui/material/ListItemIcon";
import Link from "next/link";
import React, { useState } from "react";

import { useActiveProject } from "lib/ActiveProjectContext";
import { useInterceptedRequests } from "lib/InterceptedRequestsContext";

export enum Page {
  Home,
  GetStarted,
  Intercept,
  Projects,
  ProxySetup,
  ProxyLogs,
  Sender,
  Scope,
  Settings,
}

const drawerWidth = 240;

const openedMixin = (theme: Theme): CSSObject => ({
  width: drawerWidth,
  transition: theme.transitions.create("width", {
    easing: theme.transitions.easing.sharp,
    duration: theme.transitions.duration.enteringScreen,
  }),
  overflowX: "hidden",
});

const closedMixin = (theme: Theme): CSSObject => ({
  transition: theme.transitions.create("width", {
    easing: theme.transitions.easing.sharp,
    duration: theme.transitions.duration.leavingScreen,
  }),
  overflowX: "hidden",
  width: 56,
});

const DrawerHeader = styled("div")(({ theme }) => ({
  display: "flex",
  alignItems: "center",
  justifyContent: "flex-start",
  padding: theme.spacing(0, 1),
  // necessary for content to be below app bar
  ...theme.mixins.toolbar,
}));

interface AppBarProps extends MuiAppBarProps {
  open?: boolean;
}

const AppBar = styled(MuiAppBar, {
  shouldForwardProp: (prop) => prop !== "open",
})<AppBarProps>(({ theme, open }) => ({
  backgroundColor: theme.palette.secondary.dark,
  zIndex: theme.zIndex.drawer + 1,
  transition: theme.transitions.create(["width", "margin"], {
    easing: theme.transitions.easing.sharp,
    duration: theme.transitions.duration.leavingScreen,
  }),
  ...(open && {
    marginLeft: drawerWidth,
    width: `calc(100% - ${drawerWidth}px)`,
    transition: theme.transitions.create(["width", "margin"], {
      easing: theme.transitions.easing.sharp,
      duration: theme.transitions.duration.enteringScreen,
    }),
  }),
}));

const Drawer = styled(MuiDrawer, { shouldForwardProp: (prop) => prop !== "open" })(({ theme, open }) => ({
  width: drawerWidth,
  flexShrink: 0,
  whiteSpace: "nowrap",
  boxSizing: "border-box",
  ...(open && {
    ...openedMixin(theme),
    "& .MuiDrawer-paper": openedMixin(theme),
  }),
  ...(!open && {
    ...closedMixin(theme),
    "& .MuiDrawer-paper": closedMixin(theme),
  }),
}));

const ListItemButton = styled(MuiListItemButton)<ListItemButtonProps>(({ theme }) => ({
  [theme.breakpoints.up("sm")]: {
    px: 1,
  },
  "&.MuiListItemButton-root": {
    "&.Mui-selected": {
      backgroundColor: theme.palette.primary.main,
      "& .MuiListItemIcon-root": {
        color: theme.palette.secondary.dark,
      },
      "& .MuiListItemText-root": {
        color: theme.palette.secondary.dark,
      },
    },
  },
}));

const ListItemIcon = styled(MuiListItemIcon)<ListItemIconProps>(() => ({
  minWidth: 42,
}));

interface Props {
  children: React.ReactNode;
  title: string;
  page: Page;
}

export function Layout({ title, page, children }: Props): JSX.Element {
  const activeProject = useActiveProject();
  const interceptedRequests = useInterceptedRequests();
  const theme = useTheme();
  const [open, setOpen] = useState(false);

  const handleDrawerOpen = () => {
    setOpen(true);
  };

  const handleDrawerClose = () => {
    setOpen(false);
  };

  const SiteTitle = styled("span")({
    ...(title !== "" && {
      color: theme.palette.primary.main,
      marginRight: 4,
    }),
  });

  return (
    <Box sx={{ display: "flex", height: "100%" }}>
      <AppBar position="fixed" open={open}>
        <Toolbar>
          <IconButton
            color="inherit"
            aria-label="Open drawer"
            onClick={handleDrawerOpen}
            edge="start"
            sx={{
              mr: 5,
              ...(open && { display: "none" }),
            }}
          >
            <MenuIcon />
          </IconButton>
          <Box
            sx={{
              display: "flex",
              justifyContent: "space-around",
              width: "100%",
            }}
          >
            <Typography variant="h5" noWrap sx={{ width: "100%" }}>
              <SiteTitle>Hetty://</SiteTitle>
              {title}
            </Typography>
            <Box sx={{ flexShrink: 0, pt: 0.75 }}>v{process.env.NEXT_PUBLIC_VERSION || "0.0"}</Box>
          </Box>
        </Toolbar>
      </AppBar>
      <Drawer variant="permanent" open={open}>
        <DrawerHeader>
          <IconButton onClick={handleDrawerClose}>
            {theme.direction === "rtl" ? <ChevronRightIcon /> : <ChevronLeftIcon />}
          </IconButton>
        </DrawerHeader>
        <Divider />
        <List sx={{ p: 0 }}>
          <Link href="/" passHref>
            <ListItemButton key="home" selected={page === Page.Home}>
              <Tooltip title="Home">
                <ListItemIcon>
                  <HomeIcon />
                </ListItemIcon>
              </Tooltip>
              <ListItemText primary="Home" />
            </ListItemButton>
          </Link>
          <Link href="/proxy/logs" passHref>
            <ListItemButton key="proxyLogs" disabled={!activeProject} selected={page === Page.ProxyLogs}>
              <Tooltip title="Proxy logs">
                <ListItemIcon>
                  <FormatListBulletedIcon />
                </ListItemIcon>
              </Tooltip>
              <ListItemText primary="Logs" />
            </ListItemButton>
          </Link>
          <Link href="/proxy/intercept" passHref>
            <ListItemButton key="proxyIntercept" disabled={!activeProject} selected={page === Page.Intercept}>
              <Tooltip title="Proxy intercept">
                <ListItemIcon>
                  <Badge color="error" badgeContent={interceptedRequests?.length || 0}>
                    <AltRouteIcon />
                  </Badge>
                </ListItemIcon>
              </Tooltip>
              <ListItemText primary="Intercept" />
            </ListItemButton>
          </Link>
          <Link href="/sender" passHref>
            <ListItemButton key="sender" disabled={!activeProject} selected={page === Page.Sender}>
              <Tooltip title="Sender">
                <ListItemIcon>
                  <SendIcon />
                </ListItemIcon>
              </Tooltip>
              <ListItemText primary="Sender" />
            </ListItemButton>
          </Link>
          <Link href="/scope" passHref>
            <ListItemButton key="scope" disabled={!activeProject} selected={page === Page.Scope}>
              <Tooltip title="Scope">
                <ListItemIcon>
                  <LocationSearchingIcon />
                </ListItemIcon>
              </Tooltip>
              <ListItemText primary="Scope" />
            </ListItemButton>
          </Link>
          <Link href="/projects" passHref>
            <ListItemButton key="projects" selected={page === Page.Projects}>
              <Tooltip title="Projects">
                <ListItemIcon>
                  <FolderIcon />
                </ListItemIcon>
              </Tooltip>
              <ListItemText primary="Projects" />
            </ListItemButton>
          </Link>
        </List>
      </Drawer>
      <Box component="main" sx={{ flexGrow: 1, mx: 3, mt: 11 }}>
        {children}
      </Box>
    </Box>
  );
}


================================================
FILE: admin/src/features/intercept/components/EditRequest.tsx
================================================
import CancelIcon from "@mui/icons-material/Cancel";
import DownloadIcon from "@mui/icons-material/Download";
import SendIcon from "@mui/icons-material/Send";
import SettingsIcon from "@mui/icons-material/Settings";
import { Alert, Box, Button, CircularProgress, IconButton, Tooltip, Typography } from "@mui/material";
import { useRouter } from "next/router";
import React, { useEffect, useState } from "react";

import { useInterceptedRequests } from "lib/InterceptedRequestsContext";
import { KeyValuePair } from "lib/components/KeyValuePair";
import Link from "lib/components/Link";
import RequestTabs from "lib/components/RequestTabs";
import ResponseStatus from "lib/components/ResponseStatus";
import ResponseTabs from "lib/components/ResponseTabs";
import UrlBar, { HttpMethod, HttpProto, httpProtoMap } from "lib/components/UrlBar";
import {
  HttpProtocol,
  HttpRequest,
  useCancelRequestMutation,
  useCancelResponseMutation,
  useGetInterceptedRequestQuery,
  useModifyRequestMutation,
  useModifyResponseMutation,
} from "lib/graphql/generated";
import { queryParamsFromURL } from "lib/queryParamsFromURL";
import updateKeyPairItem from "lib/updateKeyPairItem";
import updateURLQueryParams from "lib/updateURLQueryParams";

function EditRequest(): JSX.Element {
  const router = useRouter();
  const interceptedRequests = useInterceptedRequests();

  useEffect(() => {
    // If there's no request selected and there are pending reqs, navigate to
    // the first one in the list. This helps you quickly review/handle reqs
    // without having to manually select the next one in the requests table.
    if (router.isReady && !router.query.id && interceptedRequests?.length) {
      const req = interceptedRequests[0];
      router.replace(`/proxy/intercept?id=${req.id}`);
    }
  }, [router, interceptedRequests]);

  const reqId = router.query.id as string | undefined;

  const [method, setMethod] = useState(HttpMethod.Get);
  const [url, setURL] = useState("");
  const [proto, setProto] = useState(HttpProto.Http20);
  const [queryParams, setQueryParams] = useState<KeyValuePair[]>([{ key: "", value: "" }]);
  const [reqHeaders, setReqHeaders] = useState<KeyValuePair[]>([{ key: "", value: "" }]);
  const [resHeaders, setResHeaders] = useState<KeyValuePair[]>([{ key: "", value: "" }]);
  const [reqBody, setReqBody] = useState("");
  const [resBody, setResBody] = useState("");

  const handleQueryParamChange = (key: string, value: string, idx: number) => {
    setQueryParams((prev) => {
      const updated = updateKeyPairItem(key, value, idx, prev);
      setURL((prev) => updateURLQueryParams(prev, updated));
      return updated;
    });
  };
  const handleQueryParamDelete = (idx: number) => {
    setQueryParams((prev) => {
      const updated = prev.slice(0, idx).concat(prev.slice(idx + 1, prev.length));
      setURL((prev) => updateURLQueryParams(prev, updated));
      return updated;
    });
  };

  const handleReqHeaderChange = (key: string, value: string, idx: number) => {
    setReqHeaders((prev) => updateKeyPairItem(key, value, idx, prev));
  };
  const handleReqHeaderDelete = (idx: number) => {
    setReqHeaders((prev) => prev.slice(0, idx).concat(prev.slice(idx + 1, prev.length)));
  };

  const handleResHeaderChange = (key: string, value: string, idx: number) => {
    setResHeaders((prev) => updateKeyPairItem(key, value, idx, prev));
  };
  const handleResHeaderDelete = (idx: number) => {
    setResHeaders((prev) => prev.slice(0, idx).concat(prev.slice(idx + 1, prev.length)));
  };

  const handleURLChange = (url: string) => {
    setURL(url);

    const questionMarkIndex = url.indexOf("?");
    if (questionMarkIndex === -1) {
      setQueryParams([{ key: "", value: "" }]);
      return;
    }

    const newQueryParams = queryParamsFromURL(url);
    // Push empty row.
    newQueryParams.push({ key: "", value: "" });
    setQueryParams(newQueryParams);
  };

  const getReqResult = useGetInterceptedRequestQuery({
    variables: { id: reqId as string },
    skip: reqId === undefined,
    onCompleted: ({ interceptedRequest }) => {
      if (!interceptedRequest) {
        return;
      }

      setURL(interceptedRequest.url);
      setMethod(interceptedRequest.method);
      setReqBody(interceptedRequest.body || "");

      const newQueryParams = queryParamsFromURL(interceptedRequest.url);
      // Push empty row.
      newQueryParams.push({ key: "", value: "" });
      setQueryParams(newQueryParams);

      const newReqHeaders = interceptedRequest.headers || [];
      setReqHeaders([...newReqHeaders.map(({ key, value }) => ({ key, value })), { key: "", value: "" }]);

      setResBody(interceptedRequest.response?.body || "");
      const newResHeaders = interceptedRequest.response?.headers || [];
      setResHeaders([...newResHeaders.map(({ key, value }) => ({ key, value })), { key: "", value: "" }]);
    },
  });
  const interceptedReq =
    reqId && !getReqResult?.data?.interceptedRequest?.response ? getReqResult?.data?.interceptedRequest : undefined;
  const interceptedRes = reqId ? getReqResult?.data?.interceptedRequest?.response : undefined;

  const [modifyRequest, modifyReqResult] = useModifyRequestMutation();
  const [cancelRequest, cancelReqResult] = useCancelRequestMutation();

  const [modifyResponse, modifyResResult] = useModifyResponseMutation();
  const [cancelResponse, cancelResResult] = useCancelResponseMutation();

  const onActionCompleted = () => {
    setURL("");
    setMethod(HttpMethod.Get);
    setReqBody("");
    setQueryParams([]);
    setReqHeaders([]);
    router.replace(`/proxy/intercept`);
  };

  const handleFormSubmit: React.FormEventHandler = (e) => {
    e.preventDefault();

    if (interceptedReq) {
      modifyRequest({
        variables: {
          request: {
            id: interceptedReq.id,
            url,
            method,
            proto: httpProtoMap.get(proto) || HttpProtocol.Http20,
            headers: reqHeaders.filter((kv) => kv.key !== ""),
            body: reqBody || undefined,
          },
        },
        update(cache) {
          cache.modify({
            fields: {
              interceptedRequests(existing: HttpRequest[], { readField }) {
                return existing.filter((ref) => interceptedReq.id !== readField("id", ref));
              },
            },
          });
        },
        onCompleted: onActionCompleted,
      });
    }

    if (interceptedRes) {
      modifyResponse({
        variables: {
          response: {
            requestID: interceptedRes.id,
            proto: interceptedRes.proto, // TODO: Allow modifying
            statusCode: interceptedRes.statusCode, // TODO: Allow modifying
            statusReason: interceptedRes.statusReason, // TODO: Allow modifying
            headers: resHeaders.filter((kv) => kv.key !== ""),
            body: resBody || undefined,
          },
        },
        update(cache) {
          cache.modify({
            fields: {
              interceptedRequests(existing: HttpRequest[], { readField }) {
                return existing.filter((ref) => interceptedRes.id !== readField("id", ref));
              },
            },
          });
        },
        onCompleted: onActionCompleted,
      });
    }
  };

  const handleReqCancelClick = () => {
    if (!interceptedReq) {
      return;
    }

    cancelRequest({
      variables: {
        id: interceptedReq.id,
      },
      update(cache) {
        cache.modify({
          fields: {
            interceptedRequests(existing: HttpRequest[], { readField }) {
              return existing.filter((ref) => interceptedReq.id !== readField("id", ref));
            },
          },
        });
      },
      onCompleted: onActionCompleted,
    });
  };

  const handleResCancelClick = () => {
    if (!interceptedRes) {
      return;
    }

    cancelResponse({
      variables: {
        requestID: interceptedRes.id,
      },
      update(cache) {
        cache.modify({
          fields: {
            interceptedRequests(existing: HttpRequest[], { readField }) {
              return existing.filter((ref) => interceptedRes.id !== readField("id", ref));
            },
          },
        });
      },
      onCompleted: onActionCompleted,
    });
  };

  return (
    <Box display="flex" flexDirection="column" height="100%" gap={2}>
      <Box component="form" autoComplete="off" onSubmit={handleFormSubmit}>
        <Box sx={{ display: "flex", gap: 1, flexWrap: "wrap" }}>
          <UrlBar
            method={method}
            onMethodChange={interceptedReq ? setMethod : undefined}
            url={url.toString()}
            onUrlChange={interceptedReq ? handleURLChange : undefined}
            proto={proto}
            onProtoChange={interceptedReq ? setProto : undefined}
            sx={{ flex: "1 auto" }}
          />
          {!interceptedRes && (
            <>
              <Button
                variant="contained"
                disableElevation
                type="submit"
                disabled={!interceptedReq || modifyReqResult.loading || cancelReqResult.loading}
                startIcon={modifyReqResult.loading ? <CircularProgress size={22} /> : <SendIcon />}
              >
                Send
              </Button>
              <Button
                variant="contained"
                color="error"
                disableElevation
                onClick={handleReqCancelClick}
                disabled={!interceptedReq || modifyReqResult.loading || cancelReqResult.loading}
                startIcon={cancelReqResult.loading ? <CircularProgress size={22} /> : <CancelIcon />}
              >
                Cancel
              </Button>
            </>
          )}
          {interceptedRes && (
            <>
              <Button
                variant="contained"
                disableElevation
                type="submit"
                disabled={modifyResResult.loading || cancelResResult.loading}
                endIcon={modifyResResult.loading ? <CircularProgress size={22} /> : <DownloadIcon />}
              >
                Receive
              </Button>
              <Button
                variant="contained"
                color="error"
                disableElevation
                onClick={handleResCancelClick}
                disabled={modifyResResult.loading || cancelResResult.loading}
                endIcon={cancelResResult.loading ? <CircularProgress size={22} /> : <CancelIcon />}
              >
                Cancel
              </Button>
            </>
          )}
          <Tooltip title="Intercept settings">
            <IconButton LinkComponent={Link} href="/settings#intercept">
              <SettingsIcon />
            </IconButton>
          </Tooltip>
        </Box>
        {modifyReqResult.error && (
          <Alert severity="error" sx={{ mt: 1 }}>
            {modifyReqResult.error.message}
          </Alert>
        )}
        {cancelReqResult.error && (
          <Alert severity="error" sx={{ mt: 1 }}>
            {cancelReqResult.error.message}
          </Alert>
        )}
      </Box>

      <Box flex="1 auto" overflow="scroll">
        {interceptedReq && (
          <Box sx={{ height: "100%", pb: 2 }}>
            <Typography variant="overline" color="textSecondary" sx={{ position: "absolute", right: 0, mt: 1.2 }}>
              Request
            </Typography>
            <RequestTabs
              queryParams={interceptedReq ? queryParams : []}
              headers={interceptedReq ? reqHeaders : []}
              body={reqBody}
              onQueryParamChange={interceptedReq ? handleQueryParamChange : undefined}
              onQueryParamDelete={interceptedReq ? handleQueryParamDelete : undefined}
              onHeaderChange={interceptedReq ? handleReqHeaderChange : undefined}
              onHeaderDelete={interceptedReq ? handleReqHeaderDelete : undefined}
              onBodyChange={interceptedReq ? setReqBody : undefined}
            />
          </Box>
        )}
        {interceptedRes && (
          <Box sx={{ height: "100%", pb: 2 }}>
            <Box sx={{ position: "absolute", right: 0, mt: 1.4 }}>
              <Typography variant="overline" color="textSecondary" sx={{ float: "right", ml: 3 }}>
                Response
              </Typography>
              {interceptedRes && (
                <Box sx={{ float: "right", mt: 0.2 }}>
                  <ResponseStatus
                    proto={interceptedRes.proto}
                    statusCode={interceptedRes.statusCode}
                    statusReason={interceptedRes.statusReason}
                  />
                </Box>
              )}
            </Box>
            <ResponseTabs
              headers={interceptedRes ? resHeaders : []}
              body={resBody}
              onHeaderChange={interceptedRes ? handleResHeaderChange : undefined}
              onHeaderDelete={interceptedRes ? handleResHeaderDelete : undefined}
              onBodyChange={interceptedRes ? setResBody : undefined}
              hasResponse={interceptedRes !== undefined && interceptedRes !== null}
            />
          </Box>
        )}
      </Box>
    </Box>
  );
}

export default EditRequest;


================================================
FILE: admin/src/features/intercept/components/Intercept.tsx
================================================
import { Box } from "@mui/material";

import EditRequest from "./EditRequest";
import Requests from "./Requests";

import SplitPane from "lib/components/SplitPane";

export default function Sender(): JSX.Element {
  return (
    <Box sx={{ height: "100%", position: "relative" }}>
      <SplitPane split="horizontal" size="70%">
        <Box sx={{ width: "100%", pt: "0.75rem" }}>
          <EditRequest />
        </Box>
        <Box sx={{ height: "100%", overflow: "scroll" }}>
          <Requests />
        </Box>
      </SplitPane>
    </Box>
  );
}


================================================
FILE: admin/src/features/intercept/components/Requests.tsx
================================================
import { Box, Paper, Typography } from "@mui/material";
import { useRouter } from "next/router";

import { useInterceptedRequests } from "lib/InterceptedRequestsContext";
import RequestsTable from "lib/components/RequestsTable";

function Requests(): JSX.Element {
  const interceptedRequests = useInterceptedRequests();

  const router = useRouter();
  const activeId = router.query.id as string | undefined;

  const handleRowClick = (id: string) => {
    router.push(`/proxy/intercept?id=${id}`);
  };

  return (
    <Box>
      {interceptedRequests && interceptedRequests.length > 0 && (
        <RequestsTable requests={interceptedRequests} onRowClick={handleRowClick} activeRowId={activeId} />
      )}
      <Box sx={{ mt: 2, height: "100%" }}>
        {interceptedRequests?.length === 0 && (
          <Paper variant="centered">
            <Typography>No pending intercepted requests.</Typography>
          </Paper>
        )}
      </Box>
    </Box>
  );
}

export default Requests;


================================================
FILE: admin/src/features/intercept/graphql/cancelRequest.graphql
================================================
mutation CancelRequest($id: ID!) {
  cancelRequest(id: $id) {
    success
  }
}


================================================
FILE: admin/src/features/intercept/graphql/cancelResponse.graphql
================================================
mutation CancelResponse($requestID: ID!) {
  cancelResponse(requestID: $requestID) {
    success
  }
}


================================================
FILE: admin/src/features/intercept/graphql/interceptedRequest.graphql
================================================
query GetInterceptedRequest($id: ID!) {
  interceptedRequest(id: $id) {
    id
    url
    method
    proto
    headers {
      key
      value
    }
    body
    response {
      id
      proto
      statusCode
      statusReason
      headers {
        key
        value
      }
      body
    }
  }
}


================================================
FILE: admin/src/features/intercept/graphql/modifyRequest.graphql
================================================
mutation ModifyRequest($request: ModifyRequestInput!) {
  modifyRequest(request: $request) {
    success
  }
}


================================================
FILE: admin/src/features/intercept/graphql/modifyResponse.graphql
================================================
mutation ModifyResponse($response: ModifyResponseInput!) {
  modifyResponse(response: $response) {
    success
  }
}


================================================
FILE: admin/src/features/projects/components/NewProject.tsx
================================================
import AddIcon from "@mui/icons-material/Add";
import { Box, Button, CircularProgress, TextField, Typography } from "@mui/material";
import React, { useState } from "react";

import useOpenProjectMutation from "../hooks/useOpenProjectMutation";

import { useCreateProjectMutation } from "lib/graphql/generated";

function NewProject(): JSX.Element {
  const [name, setName] = useState("");

  const [createProject, createProjResult] = useCreateProjectMutation({
    onCompleted(data) {
      setName("");
      if (data?.createProject) {
        openProject({ variables: { id: data.createProject?.id } });
      }
    },
  });
  const [openProject, openProjResult] = useOpenProjectMutation();

  const handleCreateAndOpenProjectForm = (e: React.SyntheticEvent) => {
    e.preventDefault();
    createProject({ variables: { name } });
  };

  return (
    <div>
      <Box mb={3}>
        <Typography variant="h6">New project</Typography>
      </Box>
      <form onSubmit={handleCreateAndOpenProjectForm} autoComplete="off">
        <TextField
          sx={{
            mr: 2,
          }}
          color="primary"
          size="small"
          label="Project name"
          placeholder="Project name…"
          onChange={(e) => setName(e.target.value)}
          error={Boolean(createProjResult.error || openProjResult.error)}
          helperText={
            (createProjResult.error && createProjResult.error.message) ||
            (openProjResult.error && openProjResult.error.message)
          }
        />
        <Button
          type="submit"
          variant="contained"
          color="primary"
          size="large"
          sx={{
            pt: 0.9,
            pb: 0.7,
          }}
          disabled={createProjResult.loading || openProjResult.loading}
          startIcon={createProjResult.loading || openProjResult.loading ? <CircularProgress size={22} /> : <AddIcon />}
        >
          Create & open project
        </Button>
      </form>
    </div>
  );
}

export default NewProject;


================================================
FILE: admin/src/features/projects/components/ProjectList.tsx
================================================
import CloseIcon from "@mui/icons-material/Close";
import DeleteIcon from "@mui/icons-material/Delete";
import DescriptionIcon from "@mui/icons-material/Description";
import LaunchIcon from "@mui/icons-material/Launch";
import SettingsIcon from "@mui/icons-material/Settings";
import { Alert } from "@mui/lab";
import {
  Avatar,
  Box,
  Button,
  CircularProgress,
  Dialog,
  DialogActions,
  DialogContent,
  DialogContentText,
  DialogTitle,
  IconButton,
  List,
  ListItem,
  ListItemAvatar,
  ListItemSecondaryAction,
  ListItemText,
  Paper,
  Snackbar,
  Tooltip,
  Typography,
  useTheme,
} from "@mui/material";
import React, { useState } from "react";

import useOpenProjectMutation from "../hooks/useOpenProjectMutation";

import Link, { NextLinkComposed } from "lib/components/Link";
import {
  ProjectsQuery,
  useCloseProjectMutation,
  useDeleteProjectMutation,
  useProjectsQuery,
} from "lib/graphql/generated";

function ProjectList(): JSX.Element {
  const theme = useTheme();
  const projResult = useProjectsQuery({ fetchPolicy: "network-only" });
  const [openProject, openProjResult] = useOpenProjectMutation();
  const [closeProject, closeProjResult] = useCloseProjectMutation({
    errorPolicy: "all",
    onCompleted() {
      closeProjResult.client.resetStore();
    },
    update(cache) {
      cache.modify({
        fields: {
          activeProject() {
            return null;
          },
          projects(_, { DELETE }) {
            return DELETE;
          },
          httpRequestLogFilter(_, { DELETE }) {
            return DELETE;
          },
        },
      });
    },
  });
  const [deleteProject, deleteProjResult] = useDeleteProjectMutation({
    errorPolicy: "all",
    update(cache) {
      cache.modify({
        fields: {
          projects(_, { DELETE }) {
            return DELETE;
          },
        },
      });
      setDeleteDiagOpen(false);
      setDeleteNotifOpen(true);
    },
  });

  const [deleteProj, setDeleteProj] = useState<ProjectsQuery["projects"][number]>();
  const [deleteDiagOpen, setDeleteDiagOpen] = useState(false);
  const handleDeleteButtonClick = (project: ProjectsQuery["projects"][number]) => {
    setDeleteProj(project);
    setDeleteDiagOpen(true);
  };
  const handleDeleteConfirm = () => {
    if (deleteProj) {
      deleteProject({ variables: { id: deleteProj.id } });
    }
  };
  const handleDeleteCancel = () => {
    setDeleteDiagOpen(false);
  };

  const [deleteNotifOpen, setDeleteNotifOpen] = useState(false);
  const handleCloseDeleteNotif = (_: Event | React.SyntheticEvent, reason?: string) => {
    if (reason === "clickaway") {
      return;
    }
    setDeleteNotifOpen(false);
  };

  return (
    <div>
      <Dialog open={deleteDiagOpen} onClose={handleDeleteCancel}>
        <DialogTitle>
          Delete project “<strong>{deleteProj?.name}</strong>”?
        </DialogTitle>
        <DialogContent>
          <DialogContentText>
            Deleting a project permanently removes all its data from the database. This action is irreversible.
          </DialogContentText>
          {deleteProjResult.error && (
            <Alert severity="error">Error closing project: {deleteProjResult.error.message}</Alert>
          )}
        </DialogContent>
        <DialogActions>
          <Button onClick={handleDeleteCancel} autoFocus color="secondary" variant="contained">
            Cancel
          </Button>
          <Button
            sx={{
              color: "white",
              backgroundColor: "error.main",
              "&:hover": {
                backgroundColor: "error.dark",
              },
            }}
            onClick={handleDeleteConfirm}
            disabled={deleteProjResult.loading}
            variant="contained"
          >
            Delete
          </Button>
        </DialogActions>
      </Dialog>

      <Snackbar
        open={deleteNotifOpen}
        autoHideDuration={3000}
        onClose={handleCloseDeleteNotif}
        anchorOrigin={{ horizontal: "center", vertical: "bottom" }}
      >
        <Alert onClose={handleCloseDeleteNotif} severity="info">
          Project <strong>{deleteProj?.name}</strong> was deleted.
        </Alert>
      </Snackbar>

      <Box mb={3}>
        <Typography variant="h6">Manage projects</Typography>
      </Box>

      <Box mb={4}>
        {projResult.loading && <CircularProgress />}
        {projResult.error && <Alert severity="error">Error fetching projects: {projResult.error.message}</Alert>}
        {openProjResult.error && <Alert severity="error">Error opening project: {openProjResult.error.message}</Alert>}
        {closeProjResult.error && (
          <Alert severity="error">Error closing project: {closeProjResult.error.message}</Alert>
        )}
      </Box>

      {projResult.data && projResult.data.projects.length > 0 && (
        <Paper>
          <List>
            {projResult.data.projects.map((project) => (
              <ListItem key={project.id}>
                <ListItemAvatar>
                  <Avatar
                    sx={{
                      ...(project.isActive && {
                        color: theme.palette.secondary.dark,
                        backgroundColor: theme.palette.primary.main,
                      }),
                    }}
                  >
                    <DescriptionIcon />
                  </Avatar>
                </ListItemAvatar>
                <ListItemText>
                  {project.name} {project.isActive && <em>(Active)</em>}
                </ListItemText>
                <ListItemSecondaryAction>
                  <Tooltip title="Project settings">
                    <IconButton LinkComponent={Link} href="/settings" disabled={!project.isActive}>
                      <SettingsIcon />
                    </IconButton>
                  </Tooltip>
                  {project.isActive && (
                    <Tooltip title="Close project">
                      <IconButton onClick={() => closeProject()}>
                        <CloseIcon />
                      </IconButton>
                    </Tooltip>
                  )}
                  {!project.isActive && (
                    <Tooltip title="Open project">
                      <span>
                        <IconButton
                          disabled={openProjResult.loading || projResult.loading}
                          onClick={() =>
                            openProject({
                              variables: { id: project.id },
                            })
                          }
                        >
                          <LaunchIcon />
                        </IconButton>
                      </span>
                    </Tooltip>
                  )}
                  <Tooltip title="Delete project">
                    <span>
                      <IconButton onClick={() => handleDeleteButtonClick(project)} disabled={project.isActive}>
                        <DeleteIcon />
                      </IconButton>
                    </span>
                  </Tooltip>
                </ListItemSecondaryAction>
              </ListItem>
            ))}
          </List>
        </Paper>
      )}
      {projResult.data?.projects.length === 0 && (
        <Alert severity="info">There are no projects. Create one to get started.</Alert>
      )}
    </div>
  );
}

export default ProjectList;


================================================
FILE: admin/src/features/projects/graphql/activeProject.graphql
================================================
query ActiveProject {
  activeProject {
    id
    name
    isActive
    settings {
      intercept {
        requestsEnabled
        responsesEnabled
        requestFilter
        responseFilter
      }
    }
  }
}


================================================
FILE: admin/src/features/projects/graphql/closeProject.graphql
================================================
mutation CloseProject {
  closeProject {
    success
  }
}


================================================
FILE: admin/src/features/projects/graphql/createProject.graphql
================================================
mutation CreateProject($name: String!) {
  createProject(name: $name) {
    id
    name
  }
}


================================================
FILE: admin/src/features/projects/graphql/deleteProject.graphql
================================================
mutation DeleteProject($id: ID!) {
  deleteProject(id: $id) {
    success
  }
}


================================================
FILE: admin/src/features/projects/graphql/openProject.graphql
================================================
mutation OpenProject($id: ID!) {
  openProject(id: $id) {
    id
    name
    isActive
  }
}


================================================
FILE: admin/src/features/projects/graphql/projects.graphql
================================================
query Projects {
  projects {
    id
    name
    isActive
  }
}


================================================
FILE: admin/src/features/projects/hooks/useOpenProjectMutation.ts
================================================
import { gql } from "@apollo/client";

import { useOpenProjectMutation as _useOpenProjectMutation } from "lib/graphql/generated";

export default function useOpenProjectMutation() {
  return _useOpenProjectMutation({
    errorPolicy: "all",
    update(cache, { data }) {
      cache.modify({
        fields: {
          activeProject() {
            const activeProjRef = cache.writeFragment({
              data: data?.openProject,
              fragment: gql`
                fragment ActiveProject on Project {
                  id
                  name
                  isActive
                  type
                }
              `,
            });
            return activeProjRef;
          },
          projects(_, { DELETE }) {
            cache.writeFragment({
              id: data?.openProject?.id,
              data: data?.openProject,
              fragment: gql`
                fragment OpenProject on Project {
                  id
                  name
                  isActive
                  type
                }
              `,
            });
            return DELETE;
          },
          httpRequestLogFilter(_, { DELETE }) {
            return DELETE;
          },
        },
      });
    },
  });
}


================================================
FILE: admin/src/features/reqlog/components/Actions.tsx
================================================
import AltRouteIcon from "@mui/icons-material/AltRoute";
import DeleteIcon from "@mui/icons-material/Delete";
import { Alert } from "@mui/lab";
import { Badge, Button, IconButton, Tooltip } from "@mui/material";
import Link from "next/link";

import { useActiveProject } from "lib/ActiveProjectContext";
import { useInterceptedRequests } from "lib/InterceptedRequestsContext";
import { ConfirmationDialog, useConfirmationDialog } from "lib/components/ConfirmationDialog";
import { HttpRequestLogsDocument, useClearHttpRequestLogMutation } from "lib/graphql/generated";

function Actions(): JSX.Element {
  const activeProject = useActiveProject();
  const interceptedRequests = useInterceptedRequests();
  const [clearHTTPRequestLog, clearLogsResult] = useClearHttpRequestLogMutation({
    refetchQueries: [{ query: HttpRequestLogsDocument }],
  });
  const clearHTTPConfirmationDialog = useConfirmationDialog();

  return (
    <div>
      <ConfirmationDialog
        isOpen={clearHTTPConfirmationDialog.isOpen}
        onClose={clearHTTPConfirmationDialog.close}
        onConfirm={clearHTTPRequestLog}
      >
        All proxy logs are going to be removed. This action cannot be undone.
      </ConfirmationDialog>

      {clearLogsResult.error && <Alert severity="error">Failed to clear HTTP logs: {clearLogsResult.error}</Alert>}

      {(activeProject?.settings.intercept.requestsEnabled || activeProject?.settings.intercept.responsesEnabled) && (
        <Link href="/proxy/intercept/?id=" passHref>
          <Button
            variant="contained"
            disabled={interceptedRequests === null || interceptedRequests.length === 0}
            color="primary"
            component="a"
            size="large"
            startIcon={
              <Badge color="error" badgeContent={interceptedRequests?.length || 0}>
                <AltRouteIcon />
              </Badge>
            }
            sx={{ mr: 1 }}
          >
            Review Intercepted…
          </Button>
        </Link>
      )}

      <Tooltip title="Clear all">
        <IconButton onClick={clearHTTPConfirmationDialog.open}>
          <DeleteIcon />
        </IconButton>
      </Tooltip>
    </div>
  );
}

export default Actions;


================================================
FILE: admin/src/features/reqlog/components/LogDetail.tsx
================================================
import Alert from "@mui/lab/Alert";
import { Box, CircularProgress, Paper, Typography } from "@mui/material";

import RequestDetail from "./RequestDetail";

import Response from "lib/components/Response";
import SplitPane from "lib/components/SplitPane";
import { useHttpRequestLogQuery } from "lib/graphql/generated";

interface Props {
  id?: string;
}

function LogDetail({ id }: Props): JSX.Element {
  const { loading, error, data } = useHttpRequestLogQuery({
    variables: { id: id as string },
    skip: id === undefined,
  });

  if (loading) {
    return <CircularProgress />;
  }
  if (error) {
    return <Alert severity="error">Error fetching logs details: {error.message}</Alert>;
  }

  if (data && !data.httpRequestLog) {
    return (
      <Alert severity="warning">
        Request <strong>{id}</strong> was not found.
      </Alert>
    );
  }

  if (!data?.httpRequestLog) {
    return (
      <Paper variant="centered" sx={{ mt: 2 }}>
        <Typography>Select a log entry…</Typography>
      </Paper>
    );
  }

  const reqLog = data.httpRequestLog;

  return (
    <SplitPane split="vertical" size={"50%"}>
      <RequestDetail request={reqLog} />
      {reqLog.response && (
        <Box sx={{ height: "100%", pt: 1, pl: 2, pb: 2 }}>
          <Response response={reqLog.response} />
        </Box>
      )}
    </SplitPane>
  );
}

export default LogDetail;


================================================
FILE: admin/src/features/reqlog/components/RequestDetail.tsx
================================================
import { Typography, Box } from "@mui/material";
import React from "react";

import RequestTabs from "lib/components/RequestTabs";
import { HttpRequestLogQuery } from "lib/graphql/generated";
import { queryParamsFromURL } from "lib/queryParamsFromURL";

interface Props {
  request: NonNullable<HttpRequestLogQuery["httpRequestLog"]>;
}

function RequestDetail({ request }: Props): JSX.Element {
  const { method, url, headers, body } = request;

  const parsedUrl = new URL(url);

  return (
    <Box sx={{ height: "100%", display: "flex", flexDirection: "column", pr: 2, pb: 2 }}>
      <Box sx={{ p: 2, pb: 0 }}>
        <Typography variant="overline" color="textSecondary" style={{ float: "right" }}>
          Request
        </Typography>
        <Typography
          variant="h6"
          component="h2"
          sx={{
            fontSize: "1rem",
            fontFamily: "'JetBrains Mono', monospace",
            display: "block",
            overflow: "hidden",
            whiteSpace: "nowrap",
            textOverflow: "ellipsis",
            pr: 2,
          }}
        >
          {method} {decodeURIComponent(parsedUrl.pathname + parsedUrl.search)}
        </Typography>
      </Box>

      <Box flex="1 auto" overflow="scroll">
        <RequestTabs headers={headers} queryParams={queryParamsFromURL(url)} body={body} />
      </Box>
    </Box>
  );
}

export default RequestDetail;


================================================
FILE: admin/src/features/reqlog/components/RequestLogs.tsx
================================================
import ContentCopyIcon from "@mui/icons-material/ContentCopy";
import {
  Alert,
  Box,
  IconButton,
  Link,
  MenuItem,
  Snackbar,
  styled,
  TableCell,
  TableCellProps,
  Tooltip,
} from "@mui/material";
import { useRouter } from "next/router";
import { useState } from "react";

import Actions from "./Actions";
import LogDetail from "./LogDetail";
import Search from "./Search";

import RequestsTable from "lib/components/RequestsTable";
import SplitPane from "lib/components/SplitPane";
import useContextMenu from "lib/components/useContextMenu";
import { useCreateSenderRequestFromHttpRequestLogMutation, useHttpRequestLogsQuery } from "lib/graphql/generated";

const ActionsTableCell = styled(TableCell)<TableCellProps>(() => ({
  paddingTop: 0,
  paddingBottom: 0,
}));

export function RequestLogs(): JSX.Element {
  const router = useRouter();
  const id = router.query.id as string | undefined;
  const { data } = useHttpRequestLogsQuery({
    pollInterval: 1000,
  });

  const [createSenderReqFromLog] = useCreateSenderRequestFromHttpRequestLogMutation({
    onCompleted({ createSenderRequestFromHttpRequestLog }) {
      const { id } = createSenderRequestFromHttpRequestLog;
      setNewSenderReqId(id);
      setCopiedReqNotifOpen(true);
    },
  });

  const [copyToSenderId, setCopyToSenderId] = useState("");
  const [Menu, handleContextMenu, handleContextMenuClose] = useContextMenu();

  const handleCopyToSenderClick = () => {
    createSenderReqFromLog({
      variables: {
        id: copyToSenderId,
      },
    });
    handleContextMenuClose();
  };

  const [newSenderReqId, setNewSenderReqId] = useState("");
  const [copiedReqNotifOpen, setCopiedReqNotifOpen] = useState(false);
  const handleCloseCopiedNotif = (_: Event | React.SyntheticEvent, reason?: string) => {
    if (reason === "clickaway") {
      return;
    }
    setCopiedReqNotifOpen(false);
  };

  const handleRowClick = (id: string) => {
    router.push(`/proxy/logs?id=${id}`);
  };

  const handleRowContextClick = (e: React.MouseEvent, id: string) => {
    setCopyToSenderId(id);
    handleContextMenu(e);
  };

  const actionsCell = (id: string) => (
    <ActionsTableCell>
      <Tooltip title="Copy to Sender">
        <IconButton
          size="small"
          onClick={() => {
            setCopyToSenderId(id);
            createSenderReqFromLog({
              variables: {
                id,
              },
            });
          }}
        >
          <ContentCopyIcon fontSize="small" />
        </IconButton>
      </Tooltip>
    </ActionsTableCell>
  );

  return (
    <Box display="flex" flexDirection="column" height="100%">
      <Box display="flex">
        <Box flex="1 auto">
          <Search />
        </Box>
        <Box pt={0.5}>
          <Actions />
        </Box>
      </Box>
      <Box sx={{ display: "flex", flex: "1 auto", position: "relative" }}>
        <SplitPane split="horizontal" size={"40%"}>
          <Box sx={{ width: "100%", height: "100%", pb: 2 }}>
            <Box sx={{ width: "100%", height: "100%", overflow: "scroll" }}>
              <Menu>
                <MenuItem onClick={handleCopyToSenderClick}>Copy request to Sender</MenuItem>
              </Menu>
              <Snackbar
                open={copiedReqNotifOpen}
                autoHideDuration={3000}
                onClose={handleCloseCopiedNotif}
                anchorOrigin={{ horizontal: "center", vertical: "bottom" }}
              >
                <Alert onClose={handleCloseCopiedNotif} severity="info">
                  Request was copied. <Link href={`/sender?id=${newSenderReqId}`}>Edit in Sender.</Link>
                </Alert>
              </Snackbar>
              <RequestsTable
                requests={data?.httpRequestLogs || []}
                activeRowId={id}
                actionsCell={actionsCell}
                onRowClick={handleRowClick}
                onContextMenu={handleRowContextClick}
              />
            </Box>
          </Box>
          <LogDetail id={id} />
        </SplitPane>
      </Box>
    </Box>
  );
}


================================================
FILE: admin/src/features/reqlog/components/Search.tsx
================================================
import FilterListIcon from "@mui/icons-material/FilterList";
import SearchIcon from "@mui/icons-material/Search";
import { Alert } from "@mui/lab";
import {
  Box,
  Checkbox,
  CircularProgress,
  ClickAwayListener,
  FormControlLabel,
  InputBase,
  Paper,
  Popper,
  Tooltip,
  useTheme,
} from "@mui/material";
import IconButton from "@mui/material/IconButton";
import React, { useRef, useState } from "react";

import {
  HttpRequestLogFilterDocument,
  useHttpRequestLogFilterQuery,
  useSetHttpRequestLogFilterMutation,
} from "lib/graphql/generated";
import { withoutTypename } from "lib/graphql/omitTypename";

function Search(): JSX.Element {
  const theme = useTheme();

  const [searchExpr, setSearchExpr] = useState("");
  const filterResult = useHttpRequestLogFilterQuery({
    onCompleted: (data) => {
      setSearchExpr(data.httpRequestLogFilter?.searchExpression || "");
    },
  });
  const filter = filterResult.data?.httpRequestLogFilter;

  const [setFilterMutate, setFilterResult] = useSetHttpRequestLogFilterMutation({
    update(cache, { data }) {
      cache.writeQuery({
        query: HttpRequestLogFilterDocument,
        data: {
          httpRequestLogFilter: data?.setHttpRequestLogFilter,
        },
      });
    },
  });

  const filterRef = useRef<HTMLFormElement>(null);
  const [filterOpen, setFilterOpen] = useState(false);

  const handleSubmit = (e: React.SyntheticEvent) => {
    setFilterMutate({
      variables: {
        filter: {
          ...withoutTypename(filter),
          searchExpression: searchExpr,
        },
      },
    });
    setFilterOpen(false);
    e.preventDefault();
  };

  const handleClickAway = (event: MouseEvent | TouchEvent) => {
    if (filterRef?.current && filterRef.current.contains(event.target as HTMLElement)) {
      return;
    }
    setFilterOpen(false);
  };

  return (
    <Box>
      <Error prefix="Error fetching filter" error={filterResult.error} />
      <Error prefix="Error setting filter" error={setFilterResult.error} />
      <Box style={{ display: "flex", flex: 1 }}>
        <ClickAwayListener onClickAway={handleClickAway}>
          <Paper
            component="form"
            autoComplete="off"
            onSubmit={handleSubmit}
            ref={filterRef}
            sx={{
              padding: "2px 4px",
              display: "flex",
              alignItems: "center",
              width: 400,
            }}
          >
            <Tooltip title="Toggle filter options">
              <IconButton
                onClick={() => setFilterOpen(!filterOpen)}
                sx={{
                  p: 1,
                  color: filter?.onlyInScope ? "primary.main" : "inherit",
                }}
              >
                {filterResult.loading || setFilterResult.loading ? (
                  <CircularProgress sx={{ color: theme.palette.text.primary }} size={23} />
                ) : (
                  <FilterListIcon />
                )}
              </IconButton>
            </Tooltip>
            <InputBase
              sx={{
                ml: 1,
                flex: 1,
              }}
              placeholder="Search proxy logs…"
              value={searchExpr}
              onChange={(e) => setSearchExpr(e.target.value)}
              onFocus={() => setFilterOpen(true)}
              autoCorrect="false"
              spellCheck="false"
            />
            <Tooltip title="Search">
              <IconButton type="submit" sx={{ padding: 1.25 }}>
                <SearchIcon />
              </IconButton>
            </Tooltip>
            <Popper
              open={filterOpen}
              anchorEl={filterRef.current}
              placement="bottom"
              style={{ zIndex: theme.zIndex.appBar }}
            >
              <Paper
                sx={{
                  width: 400,
                  marginTop: 0.5,
                  p: 1.5,
                }}
              >
                <FormControlLabel
                  control={
                    <Checkbox
                      checked={filter?.onlyInScope ? true : false}
                      disabled={filterResult.loading || setFilterResult.loading}
                      onChange={(e) =>
                        setFilterMutate({
                          variables: {
                            filter: {
                              ...withoutTypename(filter),
                              onlyInScope: e.target.checked,
                            },
                          },
                        })
                      }
                    />
                  }
                  label="Only show in-scope requests"
                />
              </Paper>
            </Popper>
          </Paper>
        </ClickAwayListener>
      </Box>
    </Box>
  );
}

function Error(props: { prefix: string; error?: Error }) {
  if (!props.error) return null;

  return (
    <Box mb={4}>
      <Alert severity="error">
        {props.prefix}: {props.error.message}
      </Alert>
    </Box>
  );
}

export default Search;


================================================
FILE: admin/src/features/reqlog/graphql/clearHttpRequestLog.graphql
================================================
mutation ClearHTTPRequestLog {
  clearHTTPRequestLog {
    success
  }
}


================================================
FILE: admin/src/features/reqlog/graphql/httpRequestLog.graphql
================================================
query HttpRequestLog($id: ID!) {
  httpRequestLog(id: $id) {
    id
    method
    url
    proto
    headers {
      key
      value
    }
    body
    response {
      id
      proto
      headers {
        key
        value
      }
      statusCode
      statusReason
      body
    }
  }
}


================================================
FILE: admin/src/features/reqlog/graphql/httpRequestLogFilter.graphql
================================================
query HttpRequestLogFilter {
  httpRequestLogFilter {
    onlyInScope
    searchExpression
  }
}


================================================
FILE: admin/src/features/reqlog/graphql/httpRequestLogs.graphql
================================================
query HttpRequestLogs {
  httpRequestLogs {
    id
    method
    url
    timestamp
    response {
      statusCode
      statusReason
    }
  }
}


================================================
FILE: admin/src/features/reqlog/graphql/setHttpRequestLogFilter.graphql
================================================
mutation SetHttpRequestLogFilter($filter: HttpRequestLogFilterInput) {
  setHttpRequestLogFilter(filter: $filter) {
    onlyInScope
    searchExpression
  }
}


================================================
FILE: admin/src/features/reqlog/index.ts
================================================
import { RequestLogs } from "./components/RequestLogs";

export default RequestLogs;


================================================
FILE: admin/src/features/scope/components/AddRule.tsx
================================================
import { useApolloClient } from "@apollo/client";
import AddIcon from "@mui/icons-material/Add";
import { Alert } from "@mui/lab";
import {
  Box,
  Button,
  CircularProgress,
  FormControl,
  FormControlLabel,
  FormLabel,
  Radio,
  RadioGroup,
  TextField,
} from "@mui/material";
import React, { useState } from "react";

import { ScopeDocument, ScopeQuery, ScopeRule, useSetScopeMutation } from "lib/graphql/generated";

function AddRule(): JSX.Element {
  const [ruleType, setRuleType] = useState("url");
  const [expression, setExpression] = useState("");

  const client = useApolloClient();
  const [setScope, { error, loading }] = useSetScopeMutation({
    onCompleted({ setScope }) {
      client.writeQuery({
        query: ScopeDocument,
        data: { scope: setScope },
      });
      setExpression("");
    },
  });

  const handleTypeChange = (e: React.ChangeEvent, value: string) => {
    setRuleType(value);
  };
  const handleSubmit = (e: React.SyntheticEvent) => {
    e.preventDefault();
    let scope: ScopeRule[] = [];

    try {
      const data = client.readQuery<ScopeQuery>({
        query: ScopeDocument,
      });
      if (data) {
        scope = data.scope;
      }
    } catch (e) {}

    setScope({
      variables: {
        scope: [...scope.map(({ url }) => ({ url })), { url: expression }],
      },
    });
  };

  return (
    <div>
      {error && (
        <Box mb={4}>
          <Alert severity="error">Error adding rule: {error.message}</Alert>
        </Box>
      )}
      <form onSubmit={handleSubmit} autoComplete="off">
        <FormControl fullWidth>
          <FormLabel color="primary" component="legend">
            Rule Type
          </FormLabel>
          <RadioGroup row name="ruleType" value={ruleType} onChange={handleTypeChange}>
            <FormControlLabel value="url" control={<Radio />} label="URL" />
          </RadioGroup>
        </FormControl>
        <FormControl fullWidth>
          <TextField
            label="Expression"
            placeholder="^https:\/\/(.*)example.com(.*)"
            helperText="Regular expression to match on."
            color="primary"
            variant="outlined"
            required
            value={expression}
            onChange={(e) => setExpression(e.target.value)}
            InputProps={{
              sx: { fontFamily: "'JetBrains Mono', monospace" },
            }}
            InputLabelProps={{
              shrink: true,
            }}
            margin="normal"
          />
        </FormControl>
        <Box my={2}>
          <Button
            type="submit"
            variant="contained"
            color="primary"
            disabled={loading}
            startIcon={loading ? <CircularProgress size={22} /> : <AddIcon />}
          >
            Add rule
          </Button>
        </Box>
      </form>
    </div>
  );
}

export default AddRule;


================================================
FILE: admin/src/features/scope/components/RuleListItem.tsx
================================================
import { useApolloClient } from "@apollo/client";
import CodeIcon from "@mui/icons-material/Code";
import DeleteIcon from "@mui/icons-material/Delete";
import {
  Avatar,
  Chip,
  IconButton,
  ListItem,
  ListItemAvatar,
  ListItemSecondaryAction,
  ListItemText,
  Tooltip,
} from "@mui/material";
import React from "react";

import { ScopeDocument, ScopeQuery, useSetScopeMutation } from "lib/graphql/generated";

type ScopeRule = ScopeQuery["scope"][number];

type RuleListItemProps = {
  scope: ScopeQuery["scope"];
  rule: ScopeRule;
  index: number;
};

function RuleListItem({ scope, rule, index }: RuleListItemProps): JSX.Element {
  const client = useApolloClient();
  const [setScope, { loading }] = useSetScopeMutation({
    onCompleted({ setScope }) {
      client.writeQuery({
        query: ScopeDocument,
        data: { scope: setScope },
      });
    },
  });

  const handleDelete = (index: number) => {
    const clone = [...scope];
    clone.splice(index, 1);
    setScope({
      variables: {
        scope: clone.map(({ url }) => ({ url })),
      },
    });
  };

  return (
    <ListItem>
      <ListItemAvatar>
        <Avatar>
          <CodeIcon />
        </Avatar>
      </ListItemAvatar>
      <RuleListItemText rule={rule} />
      <ListItemSecondaryAction>
        <RuleTypeChip rule={rule} />
        <Tooltip title="Delete rule">
          <span style={{ marginLeft: 8 }}>
            <IconButton onClick={() => handleDelete(index)} disabled={loading}>
              <DeleteIcon />
            </IconButton>
          </span>
        </Tooltip>
      </ListItemSecondaryAction>
    </ListItem>
  );
}

function RuleListItemText({ rule }: { rule: ScopeRule }): JSX.Element {
  let text: JSX.Element = <div></div>;

  if (rule.url) {
    text = <code>{rule.url}</code>;
  }

  // TODO: Parse and handle rule.header and rule.body.

  return <ListItemText>{text}</ListItemText>;
}

function RuleTypeChip({ rule }: { rule: ScopeRule }): JSX.Element {
  let label = "Unknown";

  if (rule.url) {
    label = "URL";
  }

  return <Chip label={label} variant="outlined" />;
}

export default RuleListItem;


================================================
FILE: admin/src/features/scope/components/Rules.tsx
================================================
import { Alert } from "@mui/lab";
import { CircularProgress, List } from "@mui/material";
import React from "react";

import RuleListItem from "./RuleListItem";

import { useScopeQuery } from "lib/graphql/generated";

function Rules(): JSX.Element {
  const { loading, error, data } = useScopeQuery();

  return (
    <div>
      {loading && <CircularProgress />}
      {error && <Alert severity="error">Error fetching scope: {error.message}</Alert>}
      {data && data.scope.length > 0 && (
        <List
          sx={{
            bgcolor: "background.paper",
          }}
        >
          {data.scope.map((rule, index) => (
            <RuleListItem key={index} rule={rule} scope={data.scope} index={index} />
          ))}
        </List>
      )}
    </div>
  );
}

export default Rules;


================================================
FILE: admin/src/features/scope/graphql/scope.graphql
================================================
query Scope {
  scope {
    url
  }
}


================================================
FILE: admin/src/features/scope/graphql/setScope.graphql
================================================
mutation SetScope($scope: [ScopeRuleInput!]!) {
  setScope(scope: $scope) {
    url
  }
}


================================================
FILE: admin/src/features/sender/components/EditRequest.tsx
================================================
import AddIcon from "@mui/icons-material/Add";
import { Alert, Box, Button, Fab, Tooltip, Typography, useTheme } from "@mui/material";
import { useRouter } from "next/router";
import React, { useState } from "react";

import { KeyValuePair } from "lib/components/KeyValuePair";
import RequestTabs from "lib/components/RequestTabs";
import Response from "lib/components/Response";
import SplitPane from "lib/components/SplitPane";
import UrlBar, { HttpMethod, HttpProto, httpProtoMap } from "lib/components/UrlBar";
import {
  GetSenderRequestQuery,
  useCreateOrUpdateSenderRequestMutation,
  useGetSenderRequestQuery,
  useSendRequestMutation,
} from "lib/graphql/generated";
import { queryParamsFromURL } from "lib/queryParamsFromURL";
import updateKeyPairItem from "lib/updateKeyPairItem";
import updateURLQueryParams from "lib/updateURLQueryParams";

const defaultMethod = HttpMethod.Get;
const defaultProto = HttpProto.Http20;
const emptyKeyPair = [{ key: "", value: "" }];

function EditRequest(): JSX.Element {
  const router = useRouter();
  const reqId = router.query.id as string | undefined;

  const theme = useTheme();

  const [method, setMethod] = useState(defaultMethod);
  const [url, setURL] = useState("");
  const [proto, setProto] = useState(defaultProto);
  const [queryParams, setQueryParams] = useState<KeyValuePair[]>(emptyKeyPair);
  const [headers, setHeaders] = useState<KeyValuePair[]>(emptyKeyPair);
  const [body, setBody] = useState("");

  const handleQueryParamChange = (key: string, value: string, idx: number) => {
    setQueryParams((prev) => {
      const updated = updateKeyPairItem(key, value, idx, prev);
      setURL((prev) => updateURLQueryParams(prev, updated));
      return updated;
    });
  };
  const handleQueryParamDelete = (idx: number) => {
    setQueryParams((prev) => {
      const updated = prev.slice(0, idx).concat(prev.slice(idx + 1, prev.length));
      setURL((prev) => updateURLQueryParams(prev, updated));
      return updated;
    });
  };

  const handleHeaderChange = (key: string, value: string, idx: number) => {
    setHeaders((prev) => updateKeyPairItem(key, value, idx, prev));
  };
  const handleHeaderDelete = (idx: number) => {
    setHeaders((prev) => prev.slice(0, idx).concat(prev.slice(idx + 1, prev.length)));
  };

  const handleURLChange = (url: string) => {
    setURL(url);

    const questionMarkIndex = url.indexOf("?");
    if (questionMarkIndex === -1) {
      setQueryParams([{ key: "", value: "" }]);
      return;
    }

    const newQueryParams = queryParamsFromURL(url);
    // Push empty row.
    newQueryParams.push({ key: "", value: "" });
    setQueryParams(newQueryParams);
  };

  const [response, setResponse] = useState<NonNullable<GetSenderRequestQuery["senderRequest"]>["response"]>(null);
  const getReqResult = useGetSenderRequestQuery({
    variables: { id: reqId as string },
    skip: reqId === undefined,
    onCompleted: ({ senderRequest }) => {
      if (!senderRequest) {
        return;
      }

      setURL(senderRequest.url);
      setMethod(senderRequest.method);
      setBody(senderRequest.body || "");

      const newQueryParams = queryParamsFromURL(senderRequest.url);
      // Push empty row.
      newQueryParams.push({ key: "", value: "" });
      setQueryParams(newQueryParams);

      const newHeaders = senderRequest.headers || [];
      setHeaders([...newHeaders.map(({ key, value }) => ({ key, value })), { key: "", value: "" }]);
      setResponse(senderRequest.response);
    },
  });

  const [createOrUpdateRequest, createResult] = useCreateOrUpdateSenderRequestMutation();
  const [sendRequest, sendResult] = useSendRequestMutation();

  const createOrUpdateRequestAndSend = () => {
    const senderReq = getReqResult?.data?.senderRequest;
    createOrUpdateRequest({
      variables: {
        request: {
          // Update existing sender request if it was cloned from a request log
          // and it doesn't have a response body yet (e.g. not sent yet).
          ...(senderReq && senderReq.sourceRequestLogID && !senderReq.response && { id: senderReq.id }),
          url,
          method,
          proto: httpProtoMap.get(proto),
          headers: headers.filter((kv) => kv.key !== ""),
          body: body || undefined,
        },
      },
      onCompleted: ({ createOrUpdateSenderRequest }) => {
        const { id } = createOrUpdateSenderRequest;
        sendRequestAndPushRoute(id);
      },
    });
  };

  const sendRequestAndPushRoute = (id: string) => {
    sendRequest({
      errorPolicy: "all",
      onCompleted: () => {
        router.push(`/sender?id=${id}`);
      },
      variables: {
        id,
      },
    });
  };

  const handleFormSubmit: React.FormEventHandler = (e) => {
    e.preventDefault();
    createOrUpdateRequestAndSend();
  };

  const handleNewRequest = () => {
    setURL("");
    setMethod(defaultMethod);
    setProto(defaultProto);
    setQueryParams(emptyKeyPair);
    setHeaders(emptyKeyPair);
    setBody("");
    setResponse(null);
    router.push(`/sender`);
  };

  return (
    <Box display="flex" flexDirection="column" height="100%" gap={2}>
      <Box sx={{ position: "absolute", bottom: theme.spacing(2), right: theme.spacing(2) }}>
        <Tooltip title="New request">
          <Fab color="primary" onClick={handleNewRequest}>
            <AddIcon />
          </Fab>
        </Tooltip>
      </Box>
      <Box component="form" autoComplete="off" onSubmit={handleFormSubmit}>
        <Box sx={{ display: "flex", gap: 1, flexWrap: "wrap" }}>
          <UrlBar
            method={method}
            onMethodChange={setMethod}
            url={url.toString()}
            onUrlChange={handleURLChange}
            proto={proto}
            onProtoChange={setProto}
            sx={{ flex: "1 auto" }}
          />
          <Button
            variant="contained"
            disableElevation
            sx={{ width: "8rem" }}
            type="submit"
            disabled={createResult.loading || sendResult.loading}
          >
            Send
          </Button>
        </Box>
        {createResult.error && (
          <Alert severity="error" sx={{ mt: 1 }}>
            {createResult.error.message}
          </Alert>
        )}
        {sendResult.error && (
          <Alert severity="error" sx={{ mt: 1 }}>
            {sendResult.error.message}
          </Alert>
        )}
      </Box>

      <Box flex="1 auto" position="relative">
        <SplitPane split="vertical" size={"50%"}>
          <Box sx={{ height: "100%", mr: 2, pb: 2, position: "relative" }}>
            <Typography variant="overline" color="textSecondary" sx={{ position: "absolute", right: 0, mt: 1.2 }}>
              Request
            </Typography>
            <RequestTabs
              queryParams={queryParams}
              headers={headers}
              body={body}
              onQueryParamChange={handleQueryParamChange}
              onQueryParamDelete={handleQueryParamDelete}
              onHeaderChange={handleHeaderChange}
              onHeaderDelete={handleHeaderDelete}
              onBodyChange={setBody}
            />
          </Box>
          <Box sx={{ height: "100%", position: "relative", ml: 2, pb: 2 }}>
            <Response response={response} />
          </Box>
        </SplitPane>
      </Box>
    </Box>
  );
}

export default EditRequest;


================================================
FILE: admin/src/features/sender/components/History.tsx
================================================
import { Box, Paper, Typography } from "@mui/material";
import { useRouter } from "next/router";

import RequestsTable from "lib/components/RequestsTable";
import { useGetSenderRequestsQuery } from "lib/graphql/generated";

function History(): JSX.Element {
  const { data, loading } = useGetSenderRequestsQuery({
    pollInterval: 1000,
  });

  const router = useRouter();
  const activeId = router.query.id as string | undefined;

  const handleRowClick = (id: string) => {
    router.push(`/sender?id=${id}`);
  };

  return (
    <Box>
      {!loading && data?.senderRequests && data?.senderRequests.length > 0 && (
        <RequestsTable requests={data.senderRequests} onRowClick={handleRowClick} activeRowId={activeId} />
      )}
      <Box sx={{ mt: 2, height: "100%" }}>
        {!loading && data?.senderRequests.length === 0 && (
          <Paper variant="centered">
            <Typography>No requests created yet.</Typography>
          </Paper>
        )}
      </Box>
    </Box>
  );
}

export default History;


================================================
FILE: admin/src/features/sender/components/Sender.tsx
================================================
import { Box } from "@mui/material";

import EditRequest from "./EditRequest";
import History from "./History";

import SplitPane from "lib/components/SplitPane";

export default function Sender(): JSX.Element {
  return (
    <Box sx={{ height: "100%", position: "relative" }}>
      <SplitPane split="horizontal" size="70%">
        <Box sx={{ width: "100%", pt: "0.75rem" }}>
          <EditRequest />
        </Box>
        <Box sx={{ height: "100%", overflow: "scroll" }}>
          <History />
        </Box>
      </SplitPane>
    </Box>
  );
}


================================================
FILE: admin/src/features/sender/graphql/createOrUpdateRequest.graphql
================================================
mutation CreateOrUpdateSenderRequest($request: SenderRequestInput!) {
  createOrUpdateSenderRequest(request: $request) {
    id
  }
}


================================================
FILE: admin/src/features/sender/graphql/createSenderRequestFromRequestLog.graphql
================================================
mutation CreateSenderRequestFromHttpRequestLog($id: ID!) {
  createSenderRequestFromHttpRequestLog(id: $id) {
    id
  }
}


================================================
FILE: admin/src/features/sender/graphql/sendRequest.graphql
================================================
mutation SendRequest($id: ID!) {
  sendRequest(id: $id) {
    id
  }
}


================================================
FILE: admin/src/features/sender/graphql/senderRequest.graphql
================================================
query GetSenderRequest($id: ID!) {
  senderRequest(id: $id) {
    id
    sourceRequestLogID
    url
    method
    proto
    headers {
      key
      value
    }
    body
    timestamp
    response {
      id
      proto
      statusCode
      statusReason
      body
      headers {
        key
        value
      }
    }
  }
}


================================================
FILE: admin/src/features/sender/graphql/senderRequests.graphql
================================================
query GetSenderRequests {
  senderRequests {
    id
    url
    method
    response {
      id
      statusCode
      statusReason
    }
  }
}


================================================
FILE: admin/src/features/sender/index.ts
================================================
import Sender from "./components/Sender";

export default Sender;


================================================
FILE: admin/src/features/settings/components/Settings.tsx
================================================
import { useApolloClient } from "@apollo/client";
import { TabContext, TabPanel } from "@mui/lab";
import TabList from "@mui/lab/TabList";
import {
  Alert,
  Box,
  Button,
  CircularProgress,
  FormControl,
  FormControlLabel,
  FormHelperText,
  Snackbar,
  Switch,
  Tab,
  TextField,
  TextFieldProps,
  Typography,
} from "@mui/material";
import MaterialLink from "@mui/material/Link";
import { SwitchBaseProps } from "@mui/material/internal/SwitchBase";
import { useEffect, useState } from "react";

import { useActiveProject } from "lib/ActiveProjectContext";
import Link from "lib/components/Link";
import { ActiveProjectDocument, useUpdateInterceptSettingsMutation } from "lib/graphql/generated";
import { withoutTypename } from "lib/graphql/omitTypename";

enum TabValue {
  Intercept = "intercept",
}

function FilterTextField(props: TextFieldProps): JSX.Element {
  return (
    <TextField
      color="primary"
      variant="outlined"
      InputProps={{
        sx: { fontFamily: "'JetBrains Mono', monospace" },
        autoCorrect: "false",
        spellCheck: "false",
      }}
      InputLabelProps={{
        shrink: true,
      }}
      margin="normal"
      sx={{ mr: 1 }}
      {...props}
    />
  );
}

export default function Settings(): JSX.Element {
  const client = useApolloClient();
  const activeProject = useActiveProject();
  const [updateInterceptSettings, updateIntercepSettingsResult] = useUpdateInterceptSettingsMutation({
    onCompleted(data) {
      client.cache.updateQuery({ query: ActiveProjectDocument }, (cachedData) => ({
        activeProject: {
          ...cachedData.activeProject,
          settings: {
            ...cachedData.activeProject.settings,
            intercept: data.updateInterceptSettings,
          },
        },
      }));

      setInterceptReqFilter(data.updateInterceptSettings.requestFilter || "");
      setInterceptResFilter(data.updateInterceptSettings.responseFilter || "");
      setSettingsUpdatedOpen(true);
    },
  });

  const [interceptReqFilter, setInterceptReqFilter] = useState("");
  const [interceptResFilter, setInterceptResFilter] = useState("");

  useEffect(() => {
    setInterceptReqFilter(activeProject?.settings.intercept.requestFilter || "");
  }, [activeProject?.settings.intercept.requestFilter]);

  useEffect(() => {
    setInterceptResFilter(activeProject?.settings.intercept.responseFilter || "");
  }, [activeProject?.settings.intercept.responseFilter]);

  const handleReqInterceptEnabled: SwitchBaseProps["onChange"] = (e, checked) => {
    if (!activeProject) {
      e.preventDefault();
      return;
    }

    updateInterceptSettings({
      variables: {
        input: {
          ...withoutTypename(activeProject.settings.intercept),
          requestsEnabled: checked,
        },
      },
    });
  };

  const handleResInterceptEnabled: SwitchBaseProps["onChange"] = (e, checked) => {
    if (!activeProject) {
      e.preventDefault();
      return;
    }

    updateInterceptSettings({
      variables: {
        input: {
          ...withoutTypename(activeProject.settings.intercept),
          responsesEnabled: checked,
        },
      },
    });
  };

  const handleInterceptReqFilter = () => {
    if (!activeProject) {
      return;
    }

    updateInterceptSettings({
      variables: {
        input: {
          ...withoutTypename(activeProject.settings.intercept),
          requestFilter: interceptReqFilter,
        },
      },
    });
  };

  const handleInterceptResFilter = () => {
    if (!activeProject) {
      return;
    }

    updateInterceptSettings({
      variables: {
        input: {
          ...withoutTypename(activeProject.settings.intercept),
          responseFilter: interceptResFilter,
        },
      },
    });
  };

  const [tabValue, setTabValue] = useState(TabValue.Intercept);
  const [settingsUpdatedOpen, setSettingsUpdatedOpen] = useState(false);

  const handleSettingsUpdatedClose = (_: Event | React.SyntheticEvent, reason?: string) => {
    if (reason === "clickaway") {
      return;
    }

    setSettingsUpdatedOpen(false);
  };

  const tabSx = {
    textTransform: "none",
  };

  return (
    <Box p={4}>
      <Snackbar open={settingsUpdatedOpen} autoHideDuration={3000} onClose={handleSettingsUpdatedClose}>
        <Alert onClose={handleSettingsUpdatedClose} severity="info">
          Intercept settings have been updated.
        </Alert>
      </Snackbar>

      <Typography variant="h4" sx={{ mb: 2 }}>
        Settings
      </Typography>
      <Typography paragraph sx={{ mb: 4 }}>
        Settings allow you to tweak the behaviour of Hetty’s features.
      </Typography>
      <Typography variant="h5" sx={{ mb: 2 }}>
        Project settings
      </Typography>
      {!activeProject && (
        <Typography paragraph>
          There is no project active. To configure project settings, first <Link href="/projects">open a project</Link>.
        </Typography>
      )}
      {activeProject && (
        <>
          <TabContext value={tabValue}>
            <TabList onChange={(_, value) => setTabValue(value)} sx={{ borderBottom: 1, borderColor: "divider" }}>
              <Tab value={TabValue.Intercept} label="Intercept" sx={tabSx} />
            </TabList>

            <TabPanel value={TabValue.Intercept} sx={{ px: 0 }}>
              <Typography variant="h6" sx={{ mt: 3, mb: 1 }}>
                Requests
              </Typography>
              <FormControl sx={{ mb: 2 }}>
                <FormControlLabel
                  control={
                    <Switch
                      disabled={updateIntercepSettingsResult.loading}
                      onChange={handleReqInterceptEnabled}
                      checked={activeProject.settings.intercept.requestsEnabled}
                    />
                  }
                  label="Enable request interception"
                  labelPlacement="start"
                  sx={{ display: "inline-block", m: 0 }}
                />
                <FormHelperText>
                  When enabled, incoming HTTP requests to the proxy are stalled for{" "}
                  <Link href="/proxy/intercept">manual review</Link>.
                </FormHelperText>
              </FormControl>
              <form>
                <FormControl sx={{ width: "50%" }}>
                  <FilterTextField
                    label="Request filter"
                    placeholder={`Example: method = "GET" OR url =~ "/foobar"`}
                    value={interceptReqFilter}
                    onChange={(e) => setInterceptReqFilter(e.target.value)}
                  />
                  <FormHelperText>
                    Filter expression to match incoming requests on. When set, only matching requests are intercepted.{" "}
                    <MaterialLink
                      href="https://hetty.xyz/docs/guides/intercept?utm_source=hettyapp#request-filter"
                      target="_blank"
                    >
                      Read docs.
                    </MaterialLink>
                  </FormHelperText>
                </FormControl>
                <Button
                  type="submit"
                  variant="text"
                  color="primary"
                  size="large"
                  sx={{
                    mt: 2,
                    py: 1.8,
                  }}
                  onClick={handleInterceptReqFilter}
                  disabled={updateIntercepSettingsResult.loading}
                  startIcon={updateIntercepSettingsResult.loading ? <CircularProgress size={22} /> : undefined}
                >
                  Update
                </Button>
              </form>
              <Typography variant="h6" sx={{ mt: 3 }}>
                Responses
              </Typography>
              <FormControl sx={{ mb: 2 }}>
                <FormControlLabel
                  control={
                    <Switch
                      disabled={updateIntercepSettingsResult.loading}
                      onChange={handleResInterceptEnabled}
                      checked={activeProject.settings.intercept.responsesEnabled}
                    />
                  }
                  label="Enable response interception"
                  labelPlacement="start"
                  sx={{ display: "inline-block", m: 0 }}
                />
                <FormHelperText>
                  When enabled, HTTP responses received by the proxy are stalled for{" "}
                  <Link href="/proxy/intercept">manual review</Link>.
                </FormHelperText>
              </FormControl>
              <form>
                <FormControl sx={{ width: "50%" }}>
                  <FilterTextField
                    label="Response filter"
                    placeholder={`Example: statusCode =~ "^2" OR body =~ "foobar"`}
                    value={interceptResFilter}
                    onChange={(e) => setInterceptResFilter(e.target.value)}
                  />
                  <FormHelperText>
                    Filter expression to match received responses on. When set, only matching responses are intercepted.{" "}
                    <MaterialLink
                      href="https://hetty.xyz/docs/guides/intercept/?utm_source=hettyapp#response-filter"
                      target="_blank"
                    >
                      Read docs.
                    </MaterialLink>
                  </FormHelperText>
                </FormControl>
                <Button
                  type="submit"
                  variant="text"
                  color="primary"
                  size="large"
                  sx={{
                    mt: 2,
                    py: 1.8,
                  }}
                  onClick={handleInterceptResFilter}
                  disabled={updateIntercepSettingsResult.loading}
                  startIcon={updateIntercepSettingsResult.loading ? <CircularProgress size={22} /> : undefined}
                >
                  Update
                </Button>
              </form>
            </TabPanel>
          </TabContext>
        </>
      )}
    </Box>
  );
}


================================================
FILE: admin/src/features/settings/graphql/updateInterceptSettings.graphql
================================================
mutation UpdateInterceptSettings($input: UpdateInterceptSettingsInput!) {
  updateInterceptSettings(input: $input) {
    requestsEnabled
    responsesEnabled
    requestFilter
    responseFilter
  }
}


================================================
FILE: admin/src/lib/ActiveProjectContext.tsx
================================================
import React, { createContext, useContext } from "react";

import { Project, useActiveProjectQuery } from "./graphql/generated";

const ActiveProjectContext = createContext<Project | null>(null);

interface Props {
  children?: React.ReactNode | undefined;
}

export function ActiveProjectProvider({ children }: Props): JSX.Element {
  const { data } = useActiveProjectQuery();
  const project = data?.activeProject || null;

  return <ActiveProjectContext.Provider value={project}>{children}</ActiveProjectContext.Provider>;
}

export function useActiveProject() {
  return useContext(ActiveProjectContext);
}


================================================
FILE: admin/src/lib/InterceptedRequestsContext.tsx
================================================
import React, { createContext, useContext } from "react";

import { GetInterceptedRequestsQuery, useGetInterceptedRequestsQuery } from "./graphql/generated";

const InterceptedRequestsContext = createContext<GetInterceptedRequestsQuery["interceptedRequests"] | null>(null);

interface Props {
  children?: React.ReactNode | undefined;
}

export function InterceptedRequestsProvider({ children }: Props): JSX.Element {
  const { data } = useGetInterceptedRequestsQuery({
    pollInterval: 1000,
  });
  const reqs = data?.interceptedRequests || null;

  return <InterceptedRequestsContext.Provider value={reqs}>{children}</InterceptedRequestsContext.Provider>;
}

export function useInterceptedRequests() {
  return useContext(InterceptedRequestsContext);
}


================================================
FILE: admin/src/lib/components/ConfirmationDialog.tsx
================================================
import Button from "@mui/material/Button";
import Dialog from "@mui/material/Dialog";
import DialogActions from "@mui/material/DialogActions";
import DialogContent from "@mui/material/DialogContent";
import DialogContentText from "@mui/material/DialogContentText";
import DialogTitle from "@mui/material/DialogTitle";
import React, { useState } from "react";

export function useConfirmationDialog() {
  const [isOpen, setIsOpen] = useState(false);
  const close = () => setIsOpen(false);
  const open = () => setIsOpen(true);

  return { open, close, isOpen };
}

interface ConfirmationDialog {
  isOpen: boolean;
  onClose: () => void;
  onConfirm: () => void;
  children: React.ReactNode;
}

export function ConfirmationDialog(props: ConfirmationDialog) {
  const { onClose, onConfirm, isOpen, children } = props;

  function confirm() {
    onConfirm();
    onClose();
  }

  return (
    <Dialog
      open={isOpen}
      onClose={onClose}
      aria-labelledby="alert-dialog-title"
      aria-describedby="alert-dialog-description"
    >
      <DialogTitle id="alert-dialog-title">Are you sure?</DialogTitle>
      <DialogContent>
        <DialogContentText id="alert-dialog-description">{children}</DialogContentText>
      </DialogContent>
      <DialogActions>
        <Button onClick={onClose}>Cancel</Button>
        <Button onClick={confirm} autoFocus>
          Confirm
        </Button>
      </DialogActions>
    </Dialog>
  );
}


================================================
FILE: admin/src/lib/components/Editor.tsx
================================================
import MonacoEditor, { EditorProps } from "@monaco-editor/react";

const defaultMonacoOptions: EditorProps["options"] = {
  readOnly: true,
  wordWrap: "on",
  minimap: {
    enabled: false,
  },
};

type language = "html" | "typescript" | "json";

function languageForContentType(contentType?: string): language | undefined {
  switch (contentType?.toLowerCase()) {
    case "text/html":
    case "text/html; charset=utf-8":
      return "html";
    case "application/json":
    case "application/json; charset=utf-8":
      return "json";
    case "application/javascript":
    case "application/javascript; charset=utf-8":
      return "typescript";
    default:
      return;
  }
}

interface Props {
  content: string;
  contentType?: string;
  monacoOptions?: EditorProps["options"];
  onChange?: EditorProps["onChange"];
}

function Editor({ content, contentType, monacoOptions, onChange }: Props): JSX.Element {
  return (
    <MonacoEditor
      language={languageForContentType(contentType)}
      theme="vs-dark"
      options={{ ...defaultMonacoOptions, ...monacoOptions }}
      value={content}
      onChange={onChange}
    />
  );
}

export default Editor;


================================================
FILE: admin/src/lib/components/HttpStatusIcon.tsx
================================================
import FiberManualRecordIcon from "@mui/icons-material/FiberManualRecord";
import { SvgIconTypeMap } from "@mui/material";

interface Props {
  status: number;
}

export default function HttpStatusIcon({ status }: Props): JSX.Element {
  let color: SvgIconTypeMap["props"]["color"] = "inherit";

  switch (Math.floor(status / 100)) {
    case 2:
    case 3:
      color = "primary";
      break;
    case 4:
      color = "warning";
      break;
    case 5:
      color = "error";
      break;
  }

  return <FiberManualRecordIcon sx={{ marginTop: "-.25rem", verticalAlign: "middle" }} color={color} />;
}


================================================
FILE: admin/src/lib/components/KeyValuePair.tsx
================================================
import ClearIcon from "@mui/icons-material/Clear";
import {
  Alert,
  IconButton,
  InputBase,
  InputBaseProps,
  Snackbar,
  styled,
  Table,
  TableBody,
  TableCell,
  TableContainer,
  TableHead,
  TableRow,
  TableRowProps,
} from "@mui/material";
import { useState } from "react";

const StyledInputBase = styled(InputBase)<InputBaseProps>(() => ({
  fontSize: "0.875rem",
  "&.MuiInputBase-root input": {
    p: 0,
  },
}));

const StyledTableRow = styled(TableRow)<TableRowProps>(() => ({
  "& .delete-button": {
    visibility: "hidden",
  },
  "&:hover .delete-button": {
    visibility: "inherit",
  },
}));

export interface KeyValuePair {
  key: string;
  value: string;
}

export interface KeyValuePairTableProps {
  items: KeyValuePair[];
  onChange?: (key: string, value: string, index: number) => void;
  onDelete?: (index: number) => void;
}

export function KeyValuePairTable({ items, onChange, onDelete }: KeyValuePairTableProps): JSX.Element {
  const [copyConfOpen, setCopyConfOpen] = useState(false);

  const handleCellClick = (e: React.MouseEvent) => {
    e.preventDefault();

    const windowSel = window.getSelection();

    if (!windowSel || !document) {
      return;
    }

    const r = document.createRange();
    r.selectNode(e.currentTarget);
    windowSel.removeAllRanges();
    windowSel.addRange(r);
    document.execCommand("copy");
    windowSel.removeAllRanges();

    setCopyConfOpen(true);
  };

  const handleCopyConfClose = (_: Event | React.SyntheticEvent, reason?: string) => {
    if (reason === "clickaway") {
      return;
    }

    setCopyConfOpen(false);
  };

  return (
    <div>
      <Snackbar open={copyConfOpen} autoHideDuration={3000} onClose={handleCopyConfClose}>
        <Alert onClose={handleCopyConfClose} severity="info">
          Copied to clipboard.
        </Alert>
      </Snackbar>
      <TableContainer sx={{ overflowX: "initial" }}>
        <Table size="small" stickyHeader>
          <TableHead>
            <TableRow>
              <TableCell>Key</TableCell>
              <TableCell>Value</TableCell>
              {onDelete && <TableCell padding="checkbox"></TableCell>}
            </TableRow>
          </TableHead>
          <TableBody
            sx={{
              "td, th, input": {
                fontFamily: "'JetBrains Mono', monospace",
                fontSize: "0.75rem",
                py: 0.2,
              },
              "td span, th span": {
                display: "block",
                py: 0.7,
              },
            }}
          >
            {items.map(({ key, value }, idx) => (
              <StyledTableRow key={idx} hover>
                <TableCell
                  component="th"
                  scope="row"
                  onClick={(e) => {
                    !onChange && handleCellClick(e);
                  }}
                  sx={{
                    ...(!onChange && {
                      "&:hover": {
                        cursor: "copy",
                      },
                    }),
                  }}
                >
                  {!onChange && <span>{key}</span>}
                  {onChange && (
                    <StyledInputBase
                      size="small"
                      fullWidth
                      placeholder="Key"
                      value={key}
                      onChange={(e) => {
                        onChange && onChange(e.target.value, value, idx);
                      }}
                    />
                  )}
                </TableCell>
                <TableCell
                  onClick={(e) => {
                    !onChange && handleCellClick(e);
                  }}
                  sx={{
                    width: "60%",
                    wordBreak: "break-all",
                    ...(!onChange && {
                      "&:hover": {
                        cursor: "copy",
                      },
                    }),
                  }}
                >
                  {!onChange && value}
                  {onChange && (
                    <StyledInputBase
                      size="small"
                      fullWidth
                      placeholder="Value"
                      value={value}
                      onChange={(e) => {
                        onChange && onChange(key, e.target.value, idx);
                      }}
                    />
                  )}
                </TableCell>
                {onDelete && (
                  <TableCell>
                    <div className="delete-button">
                      <IconButton
                        size="small"
                        onClick={() => {
                          onDelete && onDelete(idx);
                        }}
                        sx={{
                          visibility: onDelete === undefined || items.length === idx + 1 ? "hidden" : "inherit",
                        }}
                      >
                        <ClearIcon fontSize="inherit" />
                      </IconButton>
                    </div>
                  </TableCell>
                )}
              </StyledTableRow>
            ))}
          </TableBody>
        </Table>
      </TableContainer>
    </div>
  );
}

export default KeyValuePairTable;


================================================
FILE: admin/src/lib/components/Link.tsx
================================================
import MuiLink, { LinkProps as MuiLinkProps } from "@mui/material/Link";
import { styled } from "@mui/material/styles";
import clsx from "clsx";
import NextLink, { LinkProps as NextLinkProps } from "next/link";
import { useRouter } from "next/router";
import * as React from "react";

// Add support for the sx prop for consistency with the other branches.
const Anchor = styled("a")({});

interface NextLinkComposedProps
  extends Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, "href">,
    Omit<NextLinkProps, "href" | "as"> {
  to: NextLinkProps["href"];
  linkAs?: NextLinkProps["as"];
}

export const NextLinkComposed = React.forwardRef<HTMLAnchorElement, NextLinkComposedProps>(function NextLinkComposed(
  props,
  ref
) {
  const { to, linkAs, replace, scroll, shallow, prefetch, locale, ...other } = props;

  return (
    <NextLink
      href={to}
      prefetch={prefetch}
      as={linkAs}
      replace={replace}
      scroll={scroll}
      shallow={shallow}
      passHref
      locale={locale}
    >
      <Anchor ref={ref} {...other} />
    </NextLink>
  );
});

export type LinkProps = {
  activeClassName?: string;
  as?: NextLinkProps["as"];
  href: NextLinkProps["href"];
  linkAs?: NextLinkProps["as"]; // Useful when the as prop is shallow by styled().
  noLinkStyle?: boolean;
} & Omit<NextLinkComposedProps, "to" | "linkAs" | "href"> &
  Omit<MuiLinkProps, "href">;

// A styled version of the Next.js Link component:
// https://nextjs.org/docs/api-reference/next/link
const Link = React.forwardRef<HTMLAnchorElement, LinkProps>(function Link(props, ref) {
  const {
    activeClassName = "active",
    as,
    className: classNameProps,
    href,
    linkAs: linkAsProp,
    locale,
    noLinkStyle,
    prefetch,
    replace,
    role, // Link don't have roles.
    scroll,
    shallow,
    ...other
  } = props;

  const router = useRouter();
  const pathname = typeof href === "string" ? href : href.pathname;
  const className = clsx(classNameProps, {
    [activeClassName]: router.pathname === pathname && activeClassName,
  });

  const isExternal = typeof href === "string" && (href.indexOf("http") === 0 || href.indexOf("mailto:") === 0);

  if (isExternal) {
    if (noLinkStyle) {
      return <Anchor className={className} href={href} ref={ref} {...other} />;
    }

    return <MuiLink className={className} href={href} ref={ref} {...other} />;
  }

  const linkAs = linkAsProp || as;
  const nextjsProps = { to: href, linkAs, replace, scroll, shallow, prefetch, locale };

  if (noLinkStyle) {
    return <NextLinkComposed className={className} ref={ref} {...nextjsProps} {...other} />;
  }

  return <MuiLink component={NextLinkComposed} className={className} ref={ref} {...nextjsProps} {...other} />;
});

export default Link;


================================================
FILE: admin/src/lib/components/RequestTabs.tsx
================================================
import { TabContext, TabList, TabPanel } from "@mui/lab";
import { Box, Tab } from "@mui/material";
import React, { useState } from "react";

import { KeyValuePairTable, KeyValuePair, KeyValuePairTableProps } from "./KeyValuePair";

import Editor from "lib/components/Editor";

enum TabValue {
  QueryParams = "queryParams",
  Headers = "headers",
  Body = "body",
}

interface RequestTabsProps {
  queryParams: KeyValuePair[];
  headers: KeyValuePair[];
  onQueryParamChange?: KeyValuePairTableProps["onChange"];
  onQueryParamDelete?: KeyValuePairTableProps["onDelete"];
  onHeaderChange?: KeyValuePairTableProps["onChange"];
  onHeaderDelete?: KeyValuePairTableProps["onDelete"];
  body?: string | null;
  onBodyChange?: (value: string) => void;
}

function RequestTabs(props: RequestTabsProps): JSX.Element {
  const {
    queryParams,
    onQueryParamChange,
    onQueryParamDelete,
    headers,
    onHeaderChange,
    onHeaderDelete,
    body,
    onBodyChange,
  } = props;
  const [tabValue, setTabValue] = useState(TabValue.QueryParams);

  const tabSx = {
    textTransform: "none",
  };

  const queryParamsLength = onQueryParamChange ? queryParams.length - 1 : queryParams.length;
  const headersLength = onHeaderChange ? headers.length - 1 : headers.length;

  return (
    <Box sx={{ display: "flex", flexDirection: "column", height: "100%" }}>
      <TabContext value={tabValue}>
        <Box sx={{ borderBottom: 1, borderColor: "divider", mb: 1 }}>
          <TabList onChange={(_, value) => setTabValue(value)}>
            <Tab
              value={TabValue.QueryParams}
              label={"Query Params" + (queryParamsLength ? ` (${queryParamsLength})` : "")}
              sx={tabSx}
            />
            <Tab value={TabValue.Headers} label={"Headers" + (headersLength ? ` (${headersLength})` : "")} sx={tabSx} />
            <Tab
              value={TabValue.Body}
              label={"Body" + (body?.length ? ` (${body.length} byte` + (body.length > 1 ? "s" : "") + ")" : "")}
              sx={tabSx}
            />
          </TabList>
        </Box>
        <Box flex="1 auto" overflow="scroll" height="100%">
          <TabPanel value={TabValue.QueryParams} sx={{ p: 0, height: "100%" }}>
            <Box>
              <KeyValuePairTable items={queryParams} onChange={onQueryParamChange} onDelete={onQueryParamDelete} />
            </Box>
          </TabPanel>
          <TabPanel value={TabValue.Headers} sx={{ p: 0, height: "100%" }}>
            <Box>
              <KeyValuePairTable items={headers} onChange={onHeaderChange} onDelete={onHeaderDelete} />
            </Box>
          </TabPanel>
          <TabPanel value={TabValue.Body} sx={{ p: 0, height: "100%" }}>
            <Editor
              content={body || ""}
              onChange={(value) => {
                onBodyChange && onBodyChange(value || "");
              }}
              monacoOptions={{ readOnly: onBodyChange === undefined }}
              contentType={headers.find(({ key }) => key.toLowerCase() === "content-type")?.value}
            />
          </TabPanel>
        </Box>
      </TabContext>
    </Box>
  );
}

export default RequestTabs;


================================================
FILE: admin/src/lib/components/RequestsTable.tsx
================================================
import {
  TableContainer,
  Table,
  TableHead,
  TableRow,
  TableCell,
  TableBody,
  styled,
  TableCellProps,
  TableRowProps,
} from "@mui/material";

import HttpStatusIcon from "./HttpStatusIcon";

import { HttpMethod } from "lib/graphql/generated";

const baseCellStyle = {
  whiteSpace: "nowrap",
  overflow: "hidden",
  textOverflow: "ellipsis",
} as const;

const MethodTableCell = styled(TableCell)<TableCellProps>(() => ({
  ...baseCellStyle,
  width: "100px",
}));

const OriginTableCell = styled(TableCell)<TableCellProps>(() => ({
  ...baseCellStyle,
  maxWidth: "100px",
}));

const PathTableCell = styled(TableCell)<TableCellProps>(() => ({
  ...baseCellStyle,
  maxWidth: "200px",
}));

const StatusTableCell = styled(TableCell)<TableCellProps>(() => ({
  ...baseCellStyle,
  width: "100px",
}));

const RequestTableRow = styled(TableRow)<TableRowProps>(() => ({
  "&:hover": {
    cursor: "pointer",
  },
}));

interface HttpRequest {
  id: string;
  url: string;
  method: HttpMethod;
  response?: HttpResponse | null;
}

interface HttpResponse {
  statusCode: number;
  statusReason: string;
  body?: string;
}

interface Props {
  requests: HttpRequest[];
  activeRowId?: string;
  actionsCell?: (id: string) => JSX.Element;
  onRowClick?: (id: string) => void;
  onContextMenu?: (e: React.MouseEvent, id: string) => void;
}

export default function RequestsTable(props: Props): JSX.Element {
  const { requests, activeRowId, actionsCell, onRowClick, onContextMenu } = props;

  return (
    <TableContainer sx={{ overflowX: "initial" }}>
      <Table size="small" stickyHeader>
        <TableHead>
          <TableRow>
            <TableCell>Method</TableCell>
            <TableCell>Origin</TableCell>
            <TableCell>Path</TableCell>
            <TableCell>Status</TableCell>
            {actionsCell && <TableCell padding="checkbox"></TableCell>}
          </TableRow>
        </TableHead>
        <TableBody>
          {requests.map(({ id, method, url, response }) => {
            const { origin, pathname, search, hash } = new URL(url);

            return (
              <RequestTableRow
                key={id}
                hover
                selected={id === activeRowId}
                onClick={() => {
                  onRowClick && onRowClick(id);
                }}
                onContextMenu={(e) => {
                  onContextMenu && onContextMenu(e, id);
                }}
              >
                <MethodTableCell>
                  <code>{method}</code>
                </MethodTableCell>
                <OriginTableCell>{origin}</OriginTableCell>
                <PathTableCell>{decodeURIComponent(pathname + search + hash)}</PathTableCell>
                <StatusTableCell>
                  {response && <Status code={response.statusCode} reason={response.statusReason} />}
                </StatusTableCell>
                {actionsCell && actionsCell(id)}
              </RequestTableRow>
            );
          })}
        </TableBody>
      </Table>
    </TableContainer>
  );
}

function Status({ code, reason }: { code: number; reason: string }): JSX.Element {
  return (
    <div>
      <HttpStatusIcon status={code} />{" "}
      <code>
        {code} {reason}
      </code>
    </div>
  );
}


================================================
FILE: admin/src/lib/components/Response.tsx
================================================
import { Box, Typography } from "@mui/material";

import ResponseTabs from "./ResponseTabs";

import ResponseStatus from "lib/components/ResponseStatus";
import { HttpResponseLog } from "lib/graphql/generated";

interface ResponseProps {
  response?: HttpResponseLog | null;
}

function Response({ response }: ResponseProps): JSX.Element {
  return (
    <Box height="100%">
      <Box sx={{ position: "absolute", right: 0, mt: 1.4 }}>
        <Typography variant="overline" color="textSecondary" sx={{ float: "right", ml: 3 }}>
          Response
        </Typography>
        {response && (
          <Box sx={{ float: "right", mt: 0.2 }}>
            <ResponseStatus
              proto={response.proto}
              statusCode={response.statusCode}
              statusReason={response.statusReason}
            />
          </Box>
        )}
      </Box>
      <ResponseTabs
        body={response?.body}
        headers={response?.headers || []}
        hasResponse={response !== undefined && response !== null}
      />
    </Box>
  );
}

export default Response;


================================================
FILE: admin/src/lib/components/ResponseStatus.tsx
================================================
import { Typography } from "@mui/material";

import HttpStatusIcon from "./HttpStatusIcon";

import { HttpProtocol } from "lib/graphql/generated";

type ResponseStatusProps = {
  proto: HttpProtocol;
  statusCode: number;
  statusReason: string;
};

function mapProto(proto: HttpProtocol): string {
  switch (proto) {
    case HttpProtocol.Http10:
      return "HTTP/1.0";
    case HttpProtocol.Http11:
      return "HTTP/1.1";
    case HttpProtocol.Http20:
      return "HTTP/2.0";
    default:
      return proto;
  }
}

export default function ResponseStatus({ proto, statusCode, statusReason }: ResponseStatusProps): JSX.Element {
  return (
    <Typography variant="h6" style={{ fontSize: "1rem", whiteSpace: "nowrap" }}>
      <HttpStatusIcon status={statusCode} />{" "}
      <Typography component="span" color="textSecondary">
        <Typography component="span" color="textSecondary" style={{ fontFamily: "'JetBrains Mono', monospace" }}>
          {mapProto(proto)}
        </Typography>
      </Typography>{" "}
      {statusCode} {statusReason}
    </Typography>
  );
}


================================================
FILE: admin/src/lib/components/ResponseTabs.tsx
================================================
import { TabContext, TabList, TabPanel } from "@mui/lab";
import { Box, Paper, Tab, Typography } from "@mui/material";
import React, { useState } from "react";

import { KeyValuePairTable, KeyValuePair, KeyValuePairTableProps } from "./KeyValuePair";

import Editor from "lib/components/Editor";

interface ResponseTabsProps {
  headers: KeyValuePair[];
  onHeaderChange?: KeyValuePairTableProps["onChange"];
  onHeaderDelete?: KeyValuePairTableProps["onDelete"];
  body?: string | null;
  onBodyChange?: (value: string) => void;
  hasResponse: boolean;
}

enum TabValue {
  Body = "body",
  Headers = "headers",
}

const reqNotSent = (
  <Paper variant="centered">
    <Typography>Response not received yet.</Typography>
  </Paper>
);

function ResponseTabs(props: ResponseTabsProps): JSX.Element {
  const { headers, onHeaderChange, onHeaderDelete, body, onBodyChange, hasResponse } = props;
  const [tabValue, setTabValue] = useState(TabValue.Body);

  const contentType = headers.find((header) => header.key.toLowerCase() === "content-type")?.value;

  const tabSx = {
    textTransform: "none",
  };

  const headersLength = onHeaderChange ? headers.length - 1 : headers.length;

  return (
    <Box height="100%" sx={{ display: "flex", flexDirection: "column" }}>
      <TabContext value={tabValue}>
        <Box sx={{ borderBottom: 1, borderColor: "divider", mb: 1 }}>
          <TabList onChange={(_, value) => setTabValue(value)}>
            <Tab
              value={TabValue.Body}
              label={"Body" + (body?.length ? ` (${body.length} byte` + (body.length > 1 ? "s" : "") + ")" : "")}
              sx={tabSx}
            />
            <Tab value={TabValue.Headers} label={"Headers" + (headersLength ? ` (${headersLength})` : "")} sx={tabSx} />
          </TabList>
        </Box>
        <Box flex="1 auto" overflow="hidden">
          <TabPanel value={TabValue.Body} sx={{ p: 0, height: "100%" }}>
            {hasResponse && (
              <Editor
                content={body || ""}
                onChange={(value) => {
                  onBodyChange && onBodyChange(value || "");
                }}
                monacoOptions={{ readOnly: onBodyChange === undefined }}
                contentType={contentType}
              />
            )}
            {!hasResponse && reqNotSent}
          </TabPanel>
          <TabPanel value={TabValue.Headers} sx={{ p: 0, height: "100%", overflow: "scroll" }}>
            {hasResponse && <KeyValuePairTable items={headers} onChange={onHeaderChange} onDelete={onHeaderDelete} />}
            {!hasResponse && reqNotSent}
          </TabPanel>
        </Box>
      </TabContext>
    </Box>
  );
}

export default ResponseTabs;


================================================
FILE: admin/src/lib/components/SplitPane.tsx
================================================
import { alpha, styled } from "@mui/material/styles";
import ReactSplitPane, { SplitPaneProps } from "react-split-pane";

const BORDER_WIDTH_FACTOR = 1.75;
const SIZE_FACTOR = 4;
const MARGIN_FACTOR = -1.75;

const SplitPane = styled(ReactSplitPane)<SplitPaneProps>(({ theme }) => ({
  ".Resizer": {
    zIndex: theme.zIndex.mobileStepper,
    boxSizing: "border-box",
    backgroundClip: "padding-box",
    backgroundColor: alpha(theme.palette.grey[400], 0.05),
  },
  ".Resizer:hover": {
    transition: "all 0.5s ease",
    backgroundColor: alpha(theme.palette.primary.main, 1),
  },

  ".Resizer.horizontal": {
    height: theme.spacing(SIZE_FACTOR),
    marginTop: theme.spacing(MARGIN_FACTOR),
    marginBottom: theme.spacing(MARGIN_FACTOR),
    borderTop: `${theme.spacing(BORDER_WIDTH_FACTOR)} solid rgba(255, 255, 255, 0)`,
    borderBottom: `${theme.spacing(BORDER_WIDTH_FACTOR)} solid rgba(255, 255, 255, 0)`,
    borderBottomColor: "rgba(255, 255, 255, 0)",
    cursor: "row-resize",
    width: "100%",
  },

  ".Resizer.vertical": {
    width: theme.spacing(SIZE_FACTOR),
    marginLeft: theme.spacing(MARGIN_FACTOR),
    marginRight: theme.spacing(MARGIN_FACTOR),
    borderLeft: `${theme.spacing(BORDER_WIDTH_FACTOR)} solid rgba(255, 255, 255, 0)`,
    borderRight: `${theme.spacing(BORDER_WIDTH_FACTOR)} solid rgba(255, 255, 255, 0)`,
    cursor: "col-resize",
  },

  ".Resizer.disabled": {
    cursor: "not-allowed",
  },

  ".Resizer.disabled:hover": {
    borderColor: "transparent",
  },

  ".Pane": {
    overflow: "hidden",
  },
}));

export default SplitPane;


================================================
FILE: admin/src/lib/components/UrlBar.tsx
================================================
import { Box, BoxProps, FormControl, InputLabel, MenuItem, Select, TextField } from "@mui/material";

import { HttpProtocol } from "lib/graphql/generated";

export enum HttpMethod {
  Get = "GET",
  Post = "POST",
  Put = "PUT",
  Patch = "PATCH",
  Delete = "DELETE",
  Head = "HEAD",
  Options = "OPTIONS",
  Connect = "CONNECT",
  Trace = "TRACE",
}

export enum HttpProto {
  Http10 = "HTTP/1.0",
  Http11 = "HTTP/1.1",
  Http20 = "HTTP/2.0",
}

export const httpProtoMap = new Map([
  [HttpProto.Http10, HttpProtocol.Http10],
  [HttpProto.Http11, HttpProtocol.Http11],
  [HttpProto.Http20, HttpProtocol.Http20],
]);

interface UrlBarProps extends BoxProps {
  method: HttpMethod;
  onMethodChange?: (method: HttpMethod) => void;
  url: string;
  onUrlChange?: (url: string) => void;
  proto: HttpProto;
  onProtoChange?: (proto: HttpProto) => void;
}

function UrlBar(props: UrlBarProps) {
  const { method, onMethodChange, url, onUrlChange, proto, onProtoChange, ...other } = props;

  return (
    <Box {...other} sx={{ ...other.sx, display: "flex" }}>
      <FormControl>
        <InputLabel id="req-method-label">Method</InputLabel>
        <Select
          labelId="req-method-label"
          id="req-method"
          value={method}
          label="Method"
          disabled={!onMethodChange}
          onChange={(e) => onMethodChange && onMethodChange(e.target.value as HttpMethod)}
          sx={{
            width: "8rem",
            ".MuiOutlinedInput-notchedOutline": {
              borderRightWidth: 0,
              borderTopRightRadius: 0,
              borderBottomRightRadius: 0,
            },
            "&:hover .MuiOutlinedInput-notchedOutline": {
              borderRightWidth: 1,
            },
          }}
        >
          {Object.values(HttpMethod).map((method) => (
            <MenuItem key={method} value={method}>
              {method}
            </MenuItem>
          ))}
        </Select>
      </FormControl>
      <TextField
        label="URL"
        placeholder="E.g. “https://example.com/foobar”"
        value={url}
        disabled={!onUrlChange}
        onChange={(e) => onUrlChange && onUrlChange(e.target.value)}
        required
        variant="outlined"
        InputLabelProps={{
          shrink: true,
        }}
        InputProps={{
          sx: {
            ".MuiOutlinedInput-notchedOutline": {
              borderRadius: 0,
            },
          },
        }}
        sx={{ flexGrow: 1 }}
      />
      <FormControl>
        <InputLabel id="req-proto-label">Protocol</InputLabel>
        <Select
          labelId="req-proto-label"
          id="req-proto"
          value={proto}
          label="Protocol"
          disabled={!onProtoChange}
          onChange={(e) => onProtoChange && onProtoChange(e.target.value as HttpProto)}
          sx={{
            ".MuiOutlinedInput-notchedOutline": {
              borderLeftWidth: 0,
              borderTopLeftRadius: 0,
              borderBottomLeftRadius: 0,
            },
            "&:hover .MuiOutlinedInput-notchedOutline": {
              borderLeftWidth: 1,
            },
          }}
        >
          {Object.values(HttpProto).map((proto) => (
            <MenuItem key={proto} value={proto}>
              {proto}
            </MenuItem>
          ))}
        </Select>
      </FormControl>
    </Box>
  );
}

export default UrlBar;


================================================
FILE: admin/src/lib/components/useContextMenu.tsx
================================================
import { Menu } from "@mui/material";
import React, { useState } from "react";

interface ContextMenuProps {
  children?: React.ReactNode;
}

export default function useContextMenu(): [
  (props: ContextMenuProps) => JSX.Element,
  (e: React.MouseEvent) => void,
  () => void
] {
  const [contextMenu, setContextMenu] = useState<{
    mouseX: number;
    mouseY: number;
  } | null>(null);

  const handleContextMenu = (event: React.MouseEvent) => {
    event.preventDefault();
    setContextMenu(
      contextMenu === null
        ? {
            mouseX: event.clientX - 2,
            mouseY: event.clientY - 4,
          }
        : // repeated contextmenu when it is already open closes it with Chrome 84 on Ubuntu
          // Other native context menus might behave different.
          // With this behavior we prevent contextmenu from the backdrop to re-locale existing context menus.
          null
    );
  };

  const handleClose = () => {
    setContextMenu(null);
  };

  const menu = ({ children }: ContextMenuProps): JSX.Element => (
    <Menu
      open={contextMenu !== null}
      onClose={handleClose}
      anchorReference="anchorPosition"
      anchorPosition={contextMenu !== null ? { top: contextMenu.mouseY, left: contextMenu.mouseX } : undefined}
    >
      {children}
    </Menu>
  );

  return [menu, handleContextMenu, handleClose];
}


================================================
FILE: admin/src/lib/graphql/generated.tsx
================================================
import { gql } from '@apollo/client';
import * as Apollo from '@apollo/client';
export type Maybe<T> = T | null;
export type InputMaybe<T> = Maybe<T>;
export type Exact<T extends { [key: string]: unknown }> = { [K in keyof T]: T[K] };
export type MakeOptional<T, K extends keyof T> = Omit<T, K> & { [SubKey in K]?: Maybe<T[SubKey]> };
export type MakeMaybe<T, K extends keyof T> = Omit<T, K> & { [SubKey in K]: Maybe<T[SubKey]> };
const defaultOptions = {} as const;
/** All built-in and custom scalars, mapped to their actual values */
export type Scalars = {
  ID: string;
  String: string;
  Boolean: boolean;
  Int: number;
  Float: number;
  Regexp: any;
  Time: any;
  URL: any;
};

export type CancelRequestResult = {
  __typename?: 'CancelRequestResult';
  success: Scalars['Boolean'];
};

export type CancelResponseResult = {
  __typename?: 'CancelResponseResult';
  success: Scalars['Boolean'];
};

export type ClearHttpRequestLogResult = {
  __typename?: 'ClearHTTPRequestLogResult';
  success: Scalars['Boolean'];
};

export type CloseProjectResult = {
  __typename?: 'CloseProjectResult';
  success: Scalars['Boolean'];
};

export type DeleteProjectResult = {
  __typename?: 'DeleteProjectResult';
  success: Scalars['Boolean'];
};

export type DeleteSenderRequestsResult = {
  __typename?: 'DeleteSenderRequestsResult';
  success: Scalars['Boolean'];
};

export type HttpHeader = {
  __typename?: 'HttpHeader';
  key: Scalars['String'];
  value: Scalars['String'];
};

export type HttpHeaderInput = {
  key: Scalars['String'];
  value: Scalars['String'];
};

export enum HttpMethod {
  Connect = 'CONNECT',
  Delete = 'DELETE',
  Get = 'GET',
  Head = 'HEAD',
  Options = 'OPTIONS',
  Patch = 'PATCH',
  Post = 'POST',
  Put = 'PUT',
  Trace = 'TRACE'
}

export enum HttpProtocol {
  Http10 = 'HTTP10',
  Http11 = 'HTTP11',
  Http20 = 'HTTP20'
}

export type HttpRequest = {
  __typename?: 'HttpRequest';
  body?: Maybe<Scalars['String']>;
  headers: Array<HttpHeader>;
  id: Scalars['ID'];
  method: HttpMethod;
  proto: HttpProtocol;
  response?: Maybe<HttpResponse>;
  url: Scalars['URL'];
};

export type HttpRequestLog = {
  __typename?: 'HttpRequestLog';
  body?: Maybe<Scalars['String']>;
  headers: Array<HttpHeader>;
  id: Scalars['ID'];
  method: HttpMethod;
  proto: Scalars['String'];
  response?: Maybe<HttpResponseLog>;
  timestamp: Scalars['Time'];
  url: Scalars['String'];
};

export type HttpRequestLogFilter = {
  __typename?: 'HttpRequestLogFilter';
  onlyInScope: Scalars['Boolean'];
  searchExpression?: Maybe<Scalars['String']>;
};

export type HttpRequestLogFilterInput = {
  onlyInScope?: InputMaybe<Scalars['Boolean']>;
  searchExpression?: InputMaybe<Scalars['String']>;
};

export type HttpResponse = {
  __typename?: 'HttpResponse';
  body?: Maybe<Scalars['String']>;
  headers: Array<HttpHeader>;
  /** Will be the same ID as its related request ID. */
  id: Scalars['ID'];
  proto: HttpProtocol;
  statusCode: Scalars['Int'];
  statusReason: Scalars['String'];
};

export type HttpResponseLog = {
  __typename?: 'HttpResponseLog';
  body?: Maybe<Scalars['String']>;
  headers: Array<HttpHeader>;
  /** Will be the same ID as its related request ID. */
  id: Scalars['ID'];
  proto: HttpProtocol;
  statusCode: Scalars['Int'];
  statusReason: Scalars['String'];
};

export type InterceptSettings = {
  __typename?: 'InterceptSettings';
  requestFilter?: Maybe<Scalars['String']>;
  requestsEnabled: Scalars['Boolean'];
  responseFilter?: Maybe<Scalars['String']>;
  responsesEnabled: Scalars['Boolean'];
};

export type ModifyRequestInput = {
  body?: InputMaybe<Scalars['String']>;
  headers?: InputMaybe<Array<HttpHeaderInput>>;
  id: Scalars['ID'];
  method: HttpMethod;
  modifyResponse?: InputMaybe<Scalars['Boolean']>;
  proto: HttpProtocol;
  url: Scalars['URL'];
};

export type ModifyRequestResult = {
  __typename?: 'ModifyRequestResult';
  success: Scalars['Boolean'];
};

export type ModifyResponseInput = {
  body?: InputMaybe<Scalars['String']>;
  headers?: InputMaybe<Array<HttpHeaderInput>>;
  proto: HttpProtocol;
  requestID: Scalars['ID'];
  statusCode: Scalars['Int'];
  statusReason: Scalars['String'];
};

export type ModifyResponseResult = {
  __typename?: 'ModifyResponseResult';
  success: Scalars['Boolean'];
};

export type Mutation = {
  __typename?: 'Mutation';
  cancelRequest: CancelRequestResult;
  cancelResponse: CancelResponseResult;
  clearHTTPRequestLog: ClearHttpRequestLogResult;
  closeProject: CloseProjectResult;
  createOrUpdateSenderRequest: SenderRequest;
  createProject?: Maybe<Project>;
  createSenderRequestFromHttpRequestLog: SenderRequest;
  deleteProject: DeleteProjectResult;
  deleteSenderRequests: DeleteSenderRequestsResult;
  modifyRequest: ModifyRequestResult;
  modifyResponse: ModifyResponseResult;
  openProject?: Maybe<Project>;
  sendRequest: SenderRequest;
  setHttpRequestLogFilter?: Maybe<HttpRequestLogFilter>;
  setScope: Array<ScopeRule>;
  setSenderRequestFilter?: Maybe<SenderRequestFilter>;
  updateInterceptSettings: InterceptSettings;
};


export type MutationCancelRequestArgs = {
  id: Scalars['ID'];
};


export type MutationCancelResponseArgs = {
  requestID: Scalars['ID'];
};


export type MutationCreateOrUpdateSenderRequestArgs = {
  request: SenderRequestInput;
};


export type MutationCreateProjectArgs = {
  name: Scalars['String'];
};


export type MutationCreateSenderRequestFromHttpRequestLogArgs = {
  id: Scalars['ID'];
};


export type MutationDeleteProjectArgs = {
  id: Scalars['ID'];
};


export type MutationModifyRequestArgs = {
  request: ModifyRequestInput;
};


export type MutationModifyResponseArgs = {
  response: ModifyResponseInput;
};


export type MutationOpenProjectArgs = {
  id: Scalars['ID'];
};


export type MutationSendRequestArgs = {
  id: Scalars['ID'];
};


export type MutationSetHttpRequestLogFilterArgs = {
  filter?: InputMaybe<HttpRequestLogFilterInput>;
};


export type MutationSetScopeArgs = {
  scope: Array<ScopeRuleInput>;
};


export type MutationSetSenderRequestFilterArgs = {
  filter?: InputMaybe<SenderRequestFilterInput>;
};


export type MutationUpdateInterceptSettingsArgs = {
  input: UpdateInterceptSettingsInput;
};

export type Project = {
  __typename?: 'Project';
  id: Scalars['ID'];
  isActive: Scalars['Boolean'];
  name: Scalars['String'];
  settings: ProjectSettings;
};

export type ProjectSettings = {
  __typename?: 'ProjectSettings';
  intercept: InterceptSettings;
};

export type Query = {
  __typename?: 'Query';
  activeProject?: Maybe<Project>;
  httpRequestLog?: Maybe<HttpRequestLog>;
  httpRequestLogFilter?: Maybe<HttpRequestLogFilter>;
  httpRequestLogs: Array<HttpRequestLog>;
  interceptedRequest?: Maybe<HttpRequest>;
  interceptedRequests: Array<HttpRequest>;
  projects: Array<Project>;
  scope: Array<ScopeRule>;
  senderRequest?: Maybe<SenderRequest>;
  senderRequests: Array<SenderRequest>;
};


export type QueryHttpRequestLogArgs = {
  id: Scalars['ID'];
};


export type QueryInterceptedRequestArgs = {
  id: Scalars['ID'];
};


export type QuerySenderRequestArgs = {
  id: Scalars['ID'];
};

export type ScopeHeader = {
  __typename?: 'ScopeHeader';
  key?: Maybe<Scalars['Regexp']>;
  value?: Maybe<Scalars['Regexp']>;
};

export type ScopeHeaderInput = {
  key?: InputMaybe<Scalars['Regexp']>;
  value?: InputMaybe<Scalars['Regexp']>;
};

export type ScopeRule = {
  __typename?: 'ScopeRule';
  body?: Maybe<Scalars['Regexp']>;
  header?: Maybe<ScopeHeader>;
  url?: Maybe<Scalars['Regexp']>;
};

export type ScopeRuleInput = {
  body?: InputMaybe<Scalars['Regexp']>;
  header?: InputMaybe<ScopeHeaderInput>;
  url?: InputMaybe<Scalars['Regexp']>;
};

export type SenderRequest = {
  __typename?: 'SenderRequest';
  body?: Maybe<Scalars['String']>;
  headers?: Maybe<Array<HttpHeader>>;
  id: Scalars['ID'];
  method: HttpMethod;
  proto: HttpProtocol;
  response?: Maybe<HttpResponseLog>;
  sourceRequestLogID?: Maybe<Scalars['ID']>;
  timestamp: Scalars['Time'];
  url: Scalars['URL'];
};

export type SenderRequestFilter = {
  __typename?: 'SenderRequestFilter';
  onlyInScope: Scalars['Boolean'];
  searchExpression?: Maybe<Scalars['String']>;
};

export type SenderRequestFilterInput = {
  onlyInScope?: InputMaybe<Scalars['Boolean']>;
  searchExpression?: InputMaybe<Scalars['String']>;
};

export type SenderRequestInput = {
  body?: InputMaybe<Scalars['String']>;
  headers?: InputMaybe<Array<HttpHeaderInput>>;
  id?: InputMaybe<Scalars['ID']>;
  method?: InputMaybe<HttpMethod>;
  proto?: InputMaybe<HttpProtocol>;
  url: Scalars['URL'];
};

export type UpdateInterceptSettingsInput = {
  requestFilter?: InputMaybe<Scalars['String']>;
  requestsEnabled: Scalars['Boolean'];
  responseFilter?: InputMaybe<Scalars['String']>;
  responsesEnabled: Scalars['Boolean'];
};

export type CancelRequestMutationVariables = Exact<{
  id: Scalars['ID'];
}>;


export type CancelRequestMutation = { __typename?: 'Mutation', cancelRequest: { __typename?: 'CancelRequestResult', success: boolean } };

export type CancelResponseMutationVariables = Exact<{
  requestID: Scalars['ID'];
}>;


export type CancelResponseMutation = { __typename?: 'Mutation', cancelResponse: { __typename?: 'CancelResponseResult', success: boolean } };

export type GetInterceptedRequestQueryVariables = Exact<{
  id: Scalars['ID'];
}>;


export type GetInterceptedRequestQuery = { __typename?: 'Query', interceptedRequest?: { __typename?: 'HttpRequest', id: string, url: any, method: HttpMethod, proto: HttpProtocol, body?: string | null, headers: Array<{ __typename?: 'HttpHeader', key: string, value: string }>, response?: { __typename?: 'HttpResponse', id: string, proto: HttpProtocol, statusCode: number, statusReason: string, body?: string | null, headers: Array<{ __typename?: 'HttpHeader', key: string, value: string }> } | null } | null };

export type ModifyRequestMutationVariables = Exact<{
  request: ModifyRequestInput;
}>;


export type ModifyRequestMutation = { __typename?: 'Mutation', modifyRequest: { __typename?: 'ModifyRequestResult', success: boolean } };

export type ModifyResponseMutationVariables = Exact<{
  response: ModifyResponseInput;
}>;


export type ModifyResponseMutation = { __typename?: 'Mutation', modifyResponse: { __typename?: 'ModifyResponseResult', success: boolean } };

export type ActiveProjectQueryVariables = Exact<{ [key: string]: never; }>;


export type ActiveProjectQuery = { __typename?: 'Query', activeProject?: { __typename?: 'Project', id: string, name: string, isActive: boolean, settings: { __typename?: 'ProjectSettings', intercept: { __typename?: 'InterceptSettings', requestsEnabled: boolean, responsesEnabled: boolean, requestFilter?: string | null, responseFilter?: string | null } } } | null };

export type CloseProjectMutationVariables = Exact<{ [key: string]: never; }>;


export type CloseProjectMutation = { __typename?: 'Mutation', closeProject: { __typename?: 'CloseProjectResult', success: boolean } };

export type CreateProjectMutationVariables = Exact<{
  name: Scalars['String'];
}>;


export type CreateProjectMutation = { __typename?: 'Mutation', createProject?: { __typename?: 'Project', id: string, name: string } | null };

export type DeleteProjectMutationVariables = Exact<{
  id: Scalars['ID'];
}>;


export type DeleteProjectMutation = { __typename?: 'Mutation', deleteProject: { __typename?: 'DeleteProjectResult', success: boolean } };

export type OpenProjectMutationVariables = Exact<{
  id: Scalars['ID'];
}>;


export type OpenProjectMutation = { __typename?: 'Mutation', openProject?: { __typename?: 'Project', id: string, name: string, isActive: boolean } | null };

export type ProjectsQueryVariables = Exact<{ [key: string]: never; }>;


export type ProjectsQuery = { __typename?: 'Query', projects: Array<{ __typename?: 'Project', id: string, name: string, isActive: boolean }> };

export type ClearHttpRequestLogMutationVariables = Exact<{ [key: string]: never; }>;


export type ClearHttpRequestLogMutation = { __typename?: 'Mutation', clearHTTPRequestLog: { __typename?: 'ClearHTTPRequestLogResult', success: boolean } };

export type HttpRequestLogQueryVariables = Exact<{
  id: Scalars['ID'];
}>;


export type HttpRequestLogQuery = { __typename?: 'Query', httpRequestLog?: { __typename?: 'HttpRequestLog', id: string, method: HttpMethod, url: string, proto: string, body?: string | null, headers: Array<{ __typename?: 'HttpHeader', key: string, value: string }>, response?: { __typename?: 'HttpResponseLog', id: string, proto: HttpProtocol, statusCode: number, statusReason: string, body?: string | null, headers: Array<{ __typename?: 'HttpHeader', key: string, value: string }> } | null } | null };

export type HttpRequestLogFilterQueryVariables = Exact<{ [key: string]: never; }>;


export type HttpRequestLogFilterQuery = { __typename?: 'Query', httpRequestLogFilter?: { __typename?: 'HttpRequestLogFilter', onlyInScope: boolean, searchExpression?: string | null } | null };

export type HttpRequestLogsQueryVariables = Exact<{ [key: string]: never; }>;


export type HttpRequestLogsQuery = { __typename?: 'Query', httpRequestLogs: Array<{ __typename?: 'HttpRequestLog', id: string, method: HttpMethod, url: string, timestamp: any, response?: { __typename?: 'HttpResponseLog', statusCode: number, statusReason: string } | null }> };

export type SetHttpRequestLogFilterMutationVariables = Exact<{
  filter?: InputMaybe<HttpRequestLogFilterInput>;
}>;


export type SetHttpRequestLogFilterMutation = { __typename?: 'Mutation', setHttpRequestLogFilter?: { __typename?: 'HttpRequestLogFilter', onlyInScope: boolean, searchExpression?: string | null } | null };

export type ScopeQueryVariables = Exact<{ [key: string]: never; }>;


export type ScopeQuery = { __typename?: 'Query', scope: Array<{ __typename?: 'ScopeRule', url?: any | null }> };

export type SetScopeMutationVariables = Exact<{
  scope: Array<ScopeRuleInput> | ScopeRuleInput;
}>;


export type SetScopeMutation = { __typename?: 'Mutation', setScope: Array<{ __typename?: 'ScopeRule', url?: any | null }> };

export type CreateOrUpdateSenderRequestMutationVariables = Exact<{
  request: SenderRequestInput;
}>;


export type CreateOrUpdateSenderRequestMutation = { __typename?: 'Mutation', createOrUpdateSenderRequest: { __typename?: 'SenderRequest', id: string } };

export type CreateSenderRequestFromHttpRequestLogMutationVariables = Exact<{
  id: Scalars['ID'];
}>;


export type CreateSenderRequestFromHttpRequestLogMutation = { __typename?: 'Mutation', createSenderRequestFromHttpRequestLog: { __typename?: 'SenderRequest', id: string } };

export type SendRequestMutationVariables = Exact<{
  id: Scalars['ID'];
}>;


export type SendRequestMutation = { __typename?: 'Mutation', sendRequest: { __typename?: 'SenderRequest', id: string } };

export type GetSenderRequestQueryVariables = Exact<{
  id: Scalars['ID'];
}>;


export type GetSenderRequestQuery = { __typename?: 'Query', senderRequest?: { __typename?: 'SenderRequest', id: string, sourceRequestLogID?: string | null, url: any, method: HttpMethod, proto: HttpProtocol, body?: string | null, timestamp: any, headers?: Array<{ __typename?: 'HttpHeader', key: string, value: string }> | null, response?: { __typename?: 'HttpResponseLog', id: string, proto: HttpProtocol, statusCode: number, statusReason: string, body?: string | null, headers: Array<{ __typename?: 'HttpHeader', key: string, value: string }> } | null } | null };

export type GetSenderRequestsQueryVariables = Exact<{ [key: string]: never; }>;


export type GetSenderRequestsQuery = { __typename?: 'Query', senderRequests: Array<{ __typename?: 'SenderRequest', id: string, url: any, method: HttpMethod, response?: { __typename?: 'HttpResponseLog', id: string, statusCode: number, statusReason: string } | null }> };

export type UpdateInterceptSettingsMutationVariables = Exact<{
  input: UpdateInterceptSettingsInput;
}>;


export type UpdateInterceptSettingsMutation = { __typename?: 'Mutation', updateInterceptSettings: { __typename?: 'InterceptSettings', requestsEnabled: boolean, responsesEnabled: boolean, requestFilter?: string | null, responseFilter?: string | null } };

export type GetInterceptedRequestsQueryVariables = Exact<{ [key: string]: never; }>;


export type GetInterceptedRequestsQuery = { __typename?: 'Query', interceptedRequests: Array<{ __typename?: 'HttpRequest', id: string, url: any, method: HttpMethod, response?: { __typename?: 'HttpResponse', statusCode: number, statusReason: string } | null }> };


export const CancelRequestDocument = gql`
    mutation CancelRequest($id: ID!) {
  cancelRequest(id: $id) {
    success
  }
}
    `;
export type CancelRequestMutationFn = Apollo.MutationFunction<CancelRequestMutation, CancelRequestMutationVariables>;

/**
 * __useCancelRequestMutation__
 *
 * To run a mutation, you first call `useCancelRequestMutation` within a React component and pass it any options that fit your needs.
 * When your component renders, `useCancelRequestMutation` returns a tuple that includes:
 * - A mutate function that you can call at any time to execute the mutation
 * - An object with fields that represent the current status of the mutation's execution
 *
 * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2;
 *
 * @example
 * const [cancelRequestMutation, { data, loading, error }] = useCancelRequestMutation({
 *   variables: {
 *      id: // value for 'id'
 *   },
 * });
 */
export function useCancelRequestMutation(baseOptions?: Apollo.MutationHookOptions<CancelRequestMutation, CancelRequestMutationVariables>) {
        const options = {...defaultOptions, ...baseOptions}
        return Apollo.useMutation<CancelRequestMutation, CancelRequestMutationVariables>(CancelRequestDocument, options);
      }
export type CancelRequestMutationHookResult = ReturnType<typeof useCancelRequestMutation>;
export type CancelRequestMutationResult = Apollo.MutationResult<CancelRequestMutation>;
export type CancelRequestMutationOptions = Apollo.BaseMutationOptions<CancelRequestMutation, CancelRequestMutationVariables>;
export const CancelResponseDocument = gql`
    mutation CancelResponse($requestID: ID!) {
  cancelResponse(requestID: $requestID) {
    success
  }
}
    `;
export type CancelResponseMutationFn = Apollo.MutationFunction<CancelResponseMutation, CancelResponseMutationVariables>;

/**
 * __useCancelResponseMutation__
 *
 * To run a mutation, you first call `useCancelResponseMutation` within a React component and pass it any options that fit your needs.
 * When your component renders, `useCancelResponseMutation` returns a tuple that includes:
 * - A mutate function that you can call at any time to execute the mutation
 * - An object with fields that represent the current status of the mutation's execution
 *
 * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2;
 *
 * @example
 * const [cancelResponseMutation, { data, loading, error }] = useCancelResponseMutation({
 *   variables: {
 *      requestID: // value for 'requestID'
 *   },
 * });
 */
export function useCancelResponseMutation(baseOptions?: Apollo.MutationHookOptions<CancelResponseMutation, CancelResponseMutationVariables>) {
        const options = {...defaultOptions, ...baseOptions}
        return Apollo.useMutation<CancelResponseMutation, CancelResponseMutationVariables>(CancelResponseDocument, options);
      }
export type CancelResponseMutationHookResult = ReturnType<typeof useCancelResponseMutation>;
export type CancelResponseMutationResult = Apollo.MutationResult<CancelResponseMutation>;
export type CancelResponseMutationOptions = Apollo.BaseMutationOptions<CancelResponseMutation, CancelResponseMutationVariables>;
export const GetInterceptedRequestDocument = gql`
    query GetInterceptedRequest($id: ID!) {
  interceptedRequest(id: $id) {
    id
    url
    method
    proto
    headers {
      key
      value
    }
    body
    response {
      id
      proto
      statusCode
      statusReason
      headers {
        key
        value
      }
      body
    }
  }
}
    `;

/**
 * __useGetInterceptedRequestQuery__
 *
 * To run a query within a React component, call `useGetInterceptedRequestQuery` and pass it any options that fit your needs.
 * When your component renders, `useGetInterceptedRequestQuery` returns an object from Apollo Client that contains loading, error, and data properties
 * you can use to render your UI.
 *
 * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
 *
 * @example
 * const { data, loading, error } = useGetInterceptedRequestQuery({
 *   variables: {
 *      id: // value for 'id'
 *   },
 * });
 */
export function useGetInterceptedRequestQuery(baseOptions: Apollo.QueryHookOptions<GetInterceptedRequestQuery, GetInterceptedRequestQueryVariables>) {
        const options = {...defaultOptions, ...baseOptions}
        return Apollo.useQuery<GetInterceptedRequestQuery, GetInterceptedRequestQueryVariables>(GetInterceptedRequestDocument, options);
      }
export function useGetInterceptedRequestLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<GetInterceptedRequestQuery, GetInterceptedRequestQueryVariables>) {
          const options = {...defaultOptions, ...baseOptions}
          return Apollo.useLazyQuery<GetInterceptedRequestQuery, GetInterceptedRequestQueryVariables>(GetInterceptedRequestDocument, options);
        }
export type GetInterceptedRequestQueryHookResult = ReturnType<typeof useGetInterceptedRequestQuery>;
export type GetInterceptedRequestLazyQueryHookResult = ReturnType<typeof useGetInterceptedRequestLazyQuery>;
export type GetInterceptedRequestQueryResult = Apollo.QueryResult<GetInterceptedRequestQuery, GetInterceptedRequestQueryVariables>;
export const ModifyRequestDocument = gql`
    mutation ModifyRequest($request: ModifyRequestInput!) {
  modifyRequest(request: $request) {
    success
  }
}
    `;
export type ModifyRequestMutationFn = Apollo.MutationFunction<ModifyRequestMutation, ModifyRequestMutationVariables>;

/**
 * __useModifyRequestMutation__
 *
 * To run a mutation, you first call `useModifyRequestMutation` within a React component and pass it any options that fit your needs.
 * When your component renders, `useModifyRequestMutation` returns a tuple that includes:
 * - A mutate function that you can call at any time to execute the mutation
 * - An object with fields that represent the current status of the mutation's execution
 *
 * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2;
 *
 * @example
 * const [modifyRequestMutation, { data, loading, error }] = useModifyRequestMutation({
 *   variables: {
 *      request: // value for 'request'
 *   },
 * });
 */
export function useModifyRequestMutation(baseOptions?: Apollo.MutationHookOptions<ModifyRequestMutation, ModifyRequestMutationVariables>) {
        const options = {...defaultOptions, ...baseOptions}
        return Apollo.useMutation<ModifyRequestMutation, ModifyRequestMutationVariables>(ModifyRequestDocument, options);
      }
export type ModifyRequestMutationHookResult = ReturnType<typeof useModifyRequestMutation>;
export type ModifyRequestMutationResult = Apollo.MutationResult<ModifyRequestMutation>;
export type ModifyRequestMutationOptions = Apollo.BaseMutationOptions<ModifyRequestMutation, ModifyRequestMutationVariables>;
export const ModifyResponseDocument = gql`
    mutation ModifyResponse($response: ModifyResponseInput!) {
  modifyResponse(response: $response) {
    success
  }
}
    `;
export type ModifyResponseMutationFn = Apollo.MutationFunction<ModifyResponseMutation, ModifyResponseMutationVariables>;

/**
 * __useModifyResponseMutation__
 *
 * To run a mutation, you first call `useModifyResponseMutation` within a React component and pass it any options that fit your needs.
 * When your component renders, `useModifyResponseMutation` returns a tuple that includes:
 * - A mutate function that you can call at any time to execute the mutation
 * - An object with fields that represent the current status of the mutation's execution
 *
 * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2;
 *
 * @example
 * const [modifyResponseMutation, { data, loading, error }] = useModifyResponseMutation({
 *   variables: {
 *      response: // value for 'response'
 *   },
 * });
 */
export function useModifyResponseMutation(baseOptions?: Apollo.MutationHookOptions<ModifyResponseMutation, ModifyResponseMutationVariables>) {
        const options = {...defaultOptions, ...baseOptions}
        return Apollo.useMutation<ModifyResponseMutation, ModifyResponseMutationVariables>(ModifyResponseDocument, options);
      }
export type ModifyResponseMutationHookResult = ReturnType<typeof useModifyResponseMutation>;
export type ModifyResponseMutationResult = Apollo.MutationResult<ModifyResponseMutation>;
export type ModifyResponseMutationOptions = Apollo.BaseMutationOptions<ModifyResponseMutation, ModifyResponseMutationVariables>;
export const ActiveProjectDocument = gql`
    query ActiveProject {
  activeProject {
    id
    name
    isActive
    settings {
      intercept {
        requestsEnabled
        responsesEnabled
        requestFilter
        responseFilter
      }
    }
  }
}
    `;

/**
 * __useActiveProjectQuery__
 *
 * To run a query within a React component, call `useActiveProjectQuery` and pass it any options that fit your needs.
 * When your component renders, `useActiveProjectQuery` returns an object from Apollo Client that contains loading, error, and data properties
 * you can use to render your UI.
 *
 * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
 *
 * @example
 * const { data, loading, error } = useActiveProjectQuery({
 *   variables: {
 *   },
 * });
 */
export function useActiveProjectQuery(baseOptions?: Apollo.QueryHookOptions<ActiveProjectQuery, ActiveProjectQueryVariables>) {
        const options = {...defaultOptions, ...baseOptions}
        return Apollo.useQuery<ActiveProjectQuery, ActiveProjectQueryVariables>(ActiveProjectDocument, options);
      }
export function useActiveProjectLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<ActiveProjectQuery, ActiveProjectQueryVariables>) {
          const options = {...defaultOptions, ...baseOptions}
          return Apollo.useLazyQuery<ActiveProjectQuery, ActiveProjectQueryVariables>(ActiveProjectDocument, options);
        }
export type ActiveProjectQueryHookResult = ReturnType<typeof useActiveProjectQuery>;
export type ActiveProjectLazyQueryHookResult = ReturnType<typeof useActiveProjectLazyQuery>;
export type ActiveProjectQueryResult = Apollo.QueryResult<ActiveProjectQuery, ActiveProjectQueryVariables>;
export const CloseProjectDocument = gql`
    mutation CloseProject {
  closeProject {
    success
  }
}
    `;
export type CloseProjectMutationFn = Apollo.MutationFunction<CloseProjectMutation, CloseProjectMutationVariables>;

/**
 * __useCloseProjectMutation__
 *
 * To run a mutation, you first call `useCloseProjectMutation` within a React component and pass it any options that fit your needs.
 * When your component renders, `useCloseProjectMutation` returns a tuple that includes:
 * - A mutate function that you can call at any time to execute the mutation
 * - An object with fields that represent the current status of the mutation's execution
 *
 * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2;
 *
 * @example
 * const [closeProjectMutation, { data, loading, error }] = useCloseProjectMutation({
 *   variables: {
 *   },
 * });
 */
export function useCloseProjectMutation(baseOptions?: Apollo.MutationHookOptions<CloseProjectMutation, CloseProjectMutationVariables>) {
        const options = {...defaultOptions, ...baseOptions}
        return Apollo.useMutation<CloseProjectMutation, CloseProjectMutationVariables>(CloseProjectDocument, options);
      }
export type CloseProjectMutationHookResult = ReturnType<typeof useCloseProjectMutation>;
export type CloseProjectMutationResult = Apollo.MutationResult<CloseProjectMutation>;
export type CloseProjectMutationOptions = Apollo.BaseMutationOptions<CloseProjectMutation, CloseProjectMutationVariables>;
export const CreateProjectDocument = gql`
    mutation CreateProject($name: String!) {
  createProject(name: $name) {
    id
    name
  }
}
    `;
export type CreateProjectMutationFn = Apollo.MutationFunction<CreateProjectMutation, CreateProjectMutationVariables>;

/**
 * __useCreateProjectMutation__
 *
 * To run a mutation, you first call `useCreateProjectMutation` within a React component and pass it any options that fit your needs.
 * When your component renders, `useCreateProjectMutation` returns a tuple that includes:
 * - A mutate function that you can call at any time to execute the mutation
 * - An object with fields that represent the current status of the mutation's execution
 *
 * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2;
 *
 * @example
 * const [createProjectMutation, { data, loading, error }] = useCreateProjectMutation({
 *   variables: {
 *      name: // value for 'name'
 *   },
 * });
 */
export function useCreateProjectMutation(baseOptions?: Apollo.MutationHookOptions<CreateProjectMutation, CreateProjectMutationVariables>) {
        const options = {...defaultOptions, ...baseOptions}
        return Apollo.useMutation<CreateProjectMutation, CreateProjectMutationVariables>(CreateProjectDocument, options);
      }
export type CreateProjectMutationHookResult = ReturnType<typeof useCreateProjectMutation>;
export type CreateProjectMutationResult = Apollo.MutationResult<CreateProjectMutation>;
export type CreateProjectMutationOptions = Apollo.BaseMutationOptions<CreateProjectMutation, CreateProjectMutationVariables>;
export const DeleteProjectDocument = gql`
    mutation DeleteProject($id: ID!) {
  deleteProject(id: $id) {
    success
  }
}
    `;
export type DeleteProjectMutationFn = Apollo.MutationFunction<DeleteProjectMutation, DeleteProjectMutationVariables>;

/**
 * __useDeleteProjectMutation__
 *
 * To run a mutation, you first call `useDeleteProjectMutation` within a React component and pass it any options that fit your needs.
 * When your component renders, `useDeleteProjectMutation` returns a tuple that includes:
 * - A mutate function that you can call at any time to execute the mutation
 * - An object with fields that represent the current status of the mutation's execution
 *
 * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2;
 *
 * @example
 * const [deleteProjectMutation, { data, loading, error }] = useDeleteProjectMutation({
 *   variables: {
 *      id: // value for 'id'
 *   },
 * });
 */
export function useDeleteProjectMutation(baseOptions?: Apollo.MutationHookOptions<DeleteProjectMutation, DeleteProjectMutationVariables>) {
        const options = {...defaultOptions, ...baseOptions}
        return Apollo.useMutation<DeleteProjectMutation, DeleteProjectMutationVariables>(DeleteProjectDocument, options);
      }
export type DeleteProjectMutationHookResult = ReturnType<typeof useDeleteProjectMutation>;
export type DeleteProjectMutationResult = Apollo.MutationResult<DeleteProjectMutation>;
export type DeleteProjectMutationOptions = Apollo.BaseMutationOptions<DeleteProjectMutation, DeleteProjectMutationVariables>;
export const OpenProjectDocument = gql`
    mutation OpenProject($id: ID!) {
  openProject(id: $id) {
    id
    name
    isActive
  }
}
    `;
export type OpenProjectMutationFn = Apollo.MutationFunction<OpenProjectMutation, OpenProjectMutationVariables>;

/**
 * __useOpenProjectMutation__
 *
 * To run a mutation, you first call `useOpenProjectMutation` within a React component and pass it any options that fit your needs.
 * When your component renders, `useOpenProjectMutation` returns a tuple that includes:
 * - A mutate function that you can call at any time to execute the mutation
 * - An object with fields that represent the current status of the mutation's execution
 *
 * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2;
 *
 * @example
 * const [openProjectMutation, { data, loading, error }] = useOpenProjectMutation({
 *   variables: {
 *      id: // value for 'id'
 *   },
 * });
 */
export function useOpenProjectMutation(baseOptions?: Apollo.MutationHookOptions<OpenProjectMutation, OpenProjectMutationVariables>) {
        const options = {...defaultOptions, ...baseOptions}
        return Apollo.useMutation<OpenProjectMutation, OpenProjectMutationVariables>(OpenProjectDocument, options);
      }
export type OpenProjectMutationHookResult = ReturnType<typeof useOpenProjectMutation>;
export type OpenProjectMutationResult = Apollo.MutationResult<OpenProjectMutation>;
export type OpenProjectMutationOptions = Apollo.BaseMutationOptions<OpenProjectMutation, OpenProjectMutationVariables>;
export const ProjectsDocument = gql`
    query Projects {
  projects {
    id
    name
    isActive
  }
}
    `;

/**
 * __useProjectsQuery__
 *
 * To run a query within a React component, call `useProjectsQuery` and pass it any options that fit your needs.
 * When your component renders, `useProjectsQuery` returns an object from Apollo Client that contains loading, error, and data properties
 * you can use to render your UI.
 *
 * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
 *
 * @example
 * const { data, loading, error } = useProjectsQuery({
 *   variables: {
 *   },
 * });
 */
export function useProjectsQuery(baseOptions?: Apollo.QueryHookOptions<ProjectsQuery, ProjectsQueryVariables>) {
        const options = {...defaultOptions, ...baseOptions}
        return Apollo.useQuery<ProjectsQuery, ProjectsQueryVariables>(ProjectsDocument, options);
      }
export function useProjectsLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<ProjectsQuery, ProjectsQueryVariables>) {
          const options = {...defaultOptions, ...baseOptions}
          return Apollo.useLazyQuery<ProjectsQuery, ProjectsQueryVariables>(ProjectsDocument, options);
        }
export type ProjectsQueryHookResult = ReturnType<typeof useProjectsQuery>;
export type ProjectsLazyQueryHookResult = ReturnType<typeof useProjectsLazyQuery>;
export type ProjectsQueryResult = Apollo.QueryResult<ProjectsQuery, ProjectsQueryVariables>;
export const ClearHttpRequestLogDocument = gql`
    mutation ClearHTTPRequestLog {
  clearHTTPRequestLog {
    success
  }
}
    `;
export type ClearHttpRequestLogMutationFn = Apollo.MutationFunction<ClearHttpRequestLogMutation, ClearHttpRequestLogMutationVariables>;

/**
 * __useClearHttpRequestLogMutation__
 *
 * To run a mutation, you first call `useClearHttpRequestLogMutation` within a React component and pass it any options that fit your needs.
 * When your component renders, `useClearHttpRequestLogMutation` returns a tuple that includes:
 * - A mutate function that you can call at any time to execute the mutation
 * - An object with fields that represent the current status of the mutation's execution
 *
 * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2;
 *
 * @example
 * const [clearHttpRequestLogMutation, { data, loading, error }] = useClearHttpRequestLogMutation({
 *   variables: {
 *   },
 * });
 */
export function useClearHttpRequestLogMutation(baseOptions?: Apollo.MutationHookOptions<ClearHttpRequestLogMutation, ClearHttpRequestLogMutationVariables>) {
        const options = {...defaultOptions, ...baseOptions}
        return Apollo.useMutation<ClearHttpRequestLogMutation, ClearHttpRequestLogMutationVariables>(ClearHttpRequestLogDocument, options);
      }
export type ClearHttpRequestLogMutationHookResult = ReturnType<typeof useClearHttpRequestLogMutation>;
export type ClearHttpRequestLogMutationResult = Apollo.MutationResult<ClearHttpRequestLogMutation>;
export type ClearHttpRequestLogMutationOptions = Apollo.BaseMutationOptions<ClearHttpRequestLogMutation, ClearHttpRequestLogMutationVariables>;
export const HttpRequestLogDocument = gql`
    query HttpRequestLog($id: ID!) {
  httpRequestLog(id: $id) {
    id
    method
    url
    proto
    headers {
      key
      value
    }
    body
    response {
      id
      proto
      headers {
        key
        value
      }
      statusCode
      statusReason
      body
    }
  }
}
    `;

/**
 * __useHttpRequestLogQuery__
 *
 * To run a query within a React component, call `useHttpRequestLogQuery` and pass it any options that fit your needs.
 * When your component renders, `useHttpRequestLogQuery` returns an object from Apollo Client that contains loading, error, and data properties
 * you can use to render your UI.
 *
 * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
 *
 * @example
 * const { data, loading, error } = useHttpRequestLogQuery({
 *   variables: {
 *      id: // value for 'id'
 *   },
 * });
 */
export function useHttpRequestLogQuery(baseOptions: Apollo.QueryHookOptions<HttpRequestLogQuery, HttpRequestLogQueryVariables>) {
        const options = {...defaultOptions, ...baseOptions}
        return Apollo.useQuery<HttpRequestLogQuery, HttpRequestLogQueryVariables>(HttpRequestLogDocument, options);
      }
export function useHttpRequestLogLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<HttpRequestLogQuery, HttpRequestLogQueryVariables>) {
          const options = {...defaultOptions, ...baseOptions}
          return Apollo.useLazyQuery<HttpRequestLogQuery, HttpRequestLogQueryVariables>(HttpRequestLogDocument, options);
        }
export type HttpRequestLogQueryHookResult = ReturnType<typeof useHttpRequestLogQuery>;
export type HttpRequestLogLazyQueryHookResult = ReturnType<typeof useHttpRequestLogLazyQuery>;
export type HttpRequestLogQueryResult = Apollo.QueryResult<HttpRequestLogQuery, HttpRequestLogQueryVariables>;
export const HttpRequestLogFilterDocument = gql`
    query HttpRequestLogFilter {
  httpRequestLogFilter {
    onlyInScope
    searchExpression
  }
}
    `;

/**
 * __useHttpRequestLogFilterQuery__
 *
 * To run a query within a React component, call `useHttpRequestLogFilterQuery` and pass it any options that fit your needs.
 * When your component renders, `useHttpRequestLogFilterQuery` returns an object from Apollo Client that contains loading, error, and data properties
 * you can use to render your UI.
 *
 * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
 *
 * @example
 * const { data, loading, error } = useHttpRequestLogFilterQuery({
 *   variables: {
 *   },
 * });
 */
export function useHttpRequestLogFilterQuery(baseOptions?: Apollo.QueryHookOptions<HttpRequestLogFilterQuery, HttpRequestLogFilterQueryVariables>) {
        const options = {...defaultOptions, ...baseOptions}
        return Apollo.useQuery<HttpRequestLogFilterQuery, HttpRequestLogFilterQueryVariables>(HttpRequestLogFilterDocument, options);
      }
export function useHttpRequestLogFilterLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<HttpRequestLogFilterQuery, HttpRequestLogFilterQueryVariables>) {
          const options = {...defaultOptions, ...baseOptions}
          return Apollo.useLazyQuery<HttpRequestLogFilterQuery, HttpRequestLogFilterQueryVariables>(HttpRequestLogFilterDocument, options);
        }
export type HttpRequestLogFilterQueryHookResult = ReturnType<typeof useHttpRequestLogFilterQuery>;
export type HttpRequestLogFilterLazyQueryHookResult = ReturnType<typeof useHttpRequestLogFilterLazyQuery>;
export type HttpRequestLogFilterQueryResult = Apollo.QueryResult<HttpRequestLogFilterQuery, HttpRequestLogFilterQueryVariables>;
export const HttpRequestLogsDocument = gql`
    query HttpRequestLogs {
  httpRequestLogs {
    id
    method
    url
    timestamp
    response {
      statusCode
      statusReason
    }
  }
}
    `;

/**
 * __useHttpRequestLogsQuery__
 *
 * To run a query within a React component, call `useHttpRequestLogsQuery` and pass it any options that fit your needs.
 * When your component renders, `useHttpRequestLogsQuery` returns an object from Apollo Client that contains loading, error, and data properties
 * you can use to render your UI.
 *
 * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
 *
 * @example
 * const { data, loading, error } = useHttpRequestLogsQuery({
 *   variables: {
 *   },
 * });
 */
export function useHttpRequestLogsQuery(baseOptions?: Apollo.QueryHookOptions<HttpRequestLogsQuery, HttpRequestLogsQueryVariables>) {
        const options = {...defaultOptions, ...baseOptions}
        return Apollo.useQuery<HttpRequestLogsQuery, HttpRequestLogsQueryVariables>(HttpRequestLogsDocument, options);
      }
export function useHttpRequestLogsLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<HttpRequestLogsQuery, HttpRequestLogsQueryVariables>) {
          const options = {...defaultOptions, ...baseOptions}
          return Apollo.useLazyQuery<HttpRequestLogsQuery, HttpRequestLogsQueryVariables>(HttpRequestLogsDocument, options);
        }
export type HttpRequestLogsQueryHookResult = ReturnType<typeof useHttpRequestLogsQuery>;
export type HttpRequestLogsLazyQueryHookResult = ReturnType<typeof useHttpRequestLogsLazyQuery>;
export type HttpRequestLogsQueryResult = Apollo.QueryResult<HttpRequestLogsQuery, HttpRequestLogsQueryVariables>;
export const SetHttpRequestLogFilterDocument = gql`
    mutation SetHttpRequestLogFilter($filter: HttpRequestLogFilterInput) {
  setHttpRequestLogFilter(filter: $filter) {
    onlyInScope
    searchExpression
  }
}
    `;
export type SetHttpRequestLogFilterMutationFn = Apollo.MutationFunction<SetHttpRequestLogFilterMutation, SetHttpRequestLogFilterMutationVariables>;

/**
 * __useSetHttpRequestLogFilterMutation__
 *
 * To run a mutation, you first call `useSetHttpRequestLogFilterMutation` within a React component and pass it any options that fit your needs.
 * When your component renders, `useSetHttpRequestLogFilterMutation` returns a tuple that includes:
 * - A mutate function that you can call at any time to execute the mutation
 * - An object with fields that represent the current status of the mutation's execution
 *
 * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2;
 *
 * @example
 * const [setHttpRequestLogFilterMutation, { data, loading, error }] = useSetHttpRequestLogFilterMutation({
 *   variables: {
 *      filter: // value for 'filter'
 *   },
 * });
 */
export function useSetHttpRequestLogFilterMutation(baseOptions?: Apollo.MutationHookOptions<SetHttpRequestLogFilterMutation, SetHttpRequestLogFilterMutationVariables>) {
        const options = {...defaultOptions, ...baseOptions}
        return Apollo.useMutation<SetHttpRequestLogFilterMutation, SetHttpRequestLogFilterMutationVariables>(SetHttpRequestLogFilterDocument, options);
      }
export type SetHttpRequestLogFilterMutationHookResult = ReturnType<typeof useSetHttpRequestLogFilterMutation>;
export type SetHttpRequestLogFilterMutationResult = Apollo.MutationResult<SetHttpRequestLogFilterMutation>;
export type SetHttpRequestLogFilterMutationOptions = Apollo.BaseMutationOptions<SetHttpRequestLogFilterMutation, SetHttpRequestLogFilterMutationVariables>;
export const ScopeDocument = gql`
    query Scope {
  scope {
    url
  }
}
    `;

/**
 * __useScopeQuery__
 *
 * To run a query within a React component, call `useScopeQuery` and pass it any options that fit your needs.
 * When your component renders, `useScopeQuery` returns an object from Apollo Client that contains loading, error, and data properties
 * you can use to render your UI.
 *
 * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
 *
 * @example
 * const { data, loading, error } = useScopeQuery({
 *   variables: {
 *   },
 * });
 */
export function useScopeQuery(baseOptions?: Apollo.QueryHookOptions<ScopeQuery, ScopeQueryVariables>) {
        const options = {...defaultOptions, ...baseOptions}
        return Apollo.useQuery<ScopeQuery, ScopeQueryVariables>(ScopeDocument, options);
      }
export function useScopeLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<ScopeQuery, ScopeQueryVariables>) {
          const options = {...defaultOptions, ...baseOptions}
          return Apollo.useLazyQuery<ScopeQuery, ScopeQueryVariables>(ScopeDocument, options);
        }
export type ScopeQueryHookResult = ReturnType<typeof useScopeQuery>;
export type ScopeLazyQueryHookResult = ReturnType<typeof useScopeLazyQuery>;
export type ScopeQueryResult = Apollo.QueryResult<ScopeQuery, ScopeQueryVariables>;
export const SetScopeDocument = gql`
    mutation SetScope($scope: [ScopeRuleInput!]!) {
  setScope(scope: $scope) {
    url
  }
}
    `;
export type SetScopeMutationFn = Apollo.MutationFunction<SetScopeMutation, SetScopeMutationVariables>;

/**
 * __useSetScopeMutation__
 *
 * To run a mutation, you first call `useSetScopeMutation` within a React component and pass it any options that fit your needs.
 * When your component renders, `useSetScopeMutation` returns a tuple that includes:
 * - A mutate function that you can call at any time to execute the mutation
 * - An object with fields that represent the current status of the mutation's execution
 *
 * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2;
 *
 * @example
 * const [setScopeMutation, { data, loading, error }] = useSetScopeMutation({
 *   variables: {
 *      scope: // value for 'scope'
 *   },
 * });
 */
export function useSetScopeMutation(baseOptions?: Apollo.MutationHookOptions<SetScopeMutation, SetScopeMutationVariables>) {
        const options = {...defaultOptions, ...baseOptions}
        return Apollo.useMutation<SetScopeMutation, SetScopeMutationVariables>(SetScopeDocument, options);
      }
export type SetScopeMutationHookResult = ReturnType<typeof useSetScopeMutation>;
export type SetScopeMutationResult = Apollo.MutationResult<SetScopeMutation>;
export type SetScopeMutationOptions = Apollo.BaseMutationOptions<SetScopeMutation, SetScopeMutationVariables>;
export const CreateOrUpdateSenderRequestDocument = gql`
    mutation CreateOrUpdateSenderRequest($request: SenderRequestInput!) {
  createOrUpdateSenderRequest(request: $request) {
    id
  }
}
    `;
export type CreateOrUpdateSenderRequestMutationFn = Apollo.MutationFunction<CreateOrUpdateSenderRequestMutation, CreateOrUpdateSenderRequestMutationVariables>;

/**
 * __useCreateOrUpdateSenderRequestMutation__
 *
 * To run a mutation, you first call `useCreateOrUpdateSenderRequestMutation` within a React component and pass it any options that fit your needs.
 * When your component renders, `useCreateOrUpdateSenderRequestMutation` returns a tuple that includes:
 * - A mutate function that you can call at any time to execute the mutation
 * - An object with fields that represent the current status of the mutation's execution
 *
 * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2;
 *
 * @example
 * const [createOrUpdateSenderRequestMutation, { data, loading, error }] = useCreateOrUpdateSenderRequestMutation({
 *   variables: {
 *      request: // value for 'request'
 *   },
 * });
 */
export function useCreateOrUpdateSenderRequestMutation(baseOptions?: Apollo.MutationHookOptions<CreateOrUpdateSenderRequestMutation, CreateOrUpdateSenderRequestMutationVariables>) {
        const options = {...defaultOptions, ...baseOptions}
        return Apollo.useMutation<CreateOrUpdateSenderRequestMutation, CreateOrUpdateSenderRequestMutationVariables>(CreateOrUpdateSenderRequestDocument, options);
      }
export type CreateOrUpdateSenderRequestMutationHookResult = ReturnType<typeof useCreateOrUpdateSenderRequestMutation>;
export type CreateOrUpdateSenderRequestMutationResult = Apollo.MutationResult<CreateOrUpdateSenderRequestMutation>;
export type CreateOrUpdateSenderRequestMutationOptions = Apollo.BaseMutationOptions<CreateOrUpdateSenderRequestMutation, CreateOrUpdateSenderRequestMutationVariables>;
export const CreateSenderRequestFromHttpRequestLogDocument = gql`
    mutation CreateSenderRequestFromHttpRequestLog($id: ID!) {
  createSenderRequestFromHttpRequestLog(id: $id) {
    id
  }
}
    `;
export type CreateSenderRequestFromHttpRequestLogMutationFn = Apollo.MutationFunction<CreateSenderRequestFromHttpRequestLogMutation, CreateSenderRequestFromHttpRequestLogMutationVariables>;

/**
 * __useCreateSenderRequestFromHttpRequestLogMutation__
 *
 * To run a mutation, you first call `useCreateSenderRequestFromHttpRequestLogMutation` within a React component and pass it any options that fit your needs.
 * When your component renders, `useCreateSenderRequestFromHttpRequestLogMutation` returns a tuple that includes:
 * - A mutate function that you can call at any time to execute the mutation
 * - An object with fields that represent the current status of the mutation's execution
 *
 * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2;
 *
 * @example
 * const [createSenderRequestFromHttpRequestLogMutation, { data, loading, error }] = useCreateSenderRequestFromHttpRequestLogMutation({
 *   variables: {
 *      id: // value for 'id'
 *   },
 * });
 */
export function useCreateSenderRequestFromHttpRequestLogMutation(baseOptions?: Apollo.MutationHookOptions<CreateSenderRequestFromHttpRequestLogMutation, CreateSenderRequestFromHttpRequestLogMutationVariables>) {
        const options = {...defaultOptions, ...baseOptions}
        return Apollo.useMutation<CreateSenderRequestFromHttpRequestLogMutation, CreateSenderRequestFromHttpRequestLogMutationVariables>(CreateSenderRequestFromHttpRequestLogDocument, options);
      }
export type CreateSenderRequestFromHttpRequestLogMutationHookResult = ReturnType<typeof useCreateSenderRequestFromHttpRequestLogMutation>;
export type CreateSenderRequestFromHttpRequestLogMutationResult = Apollo.MutationResult<CreateSenderRequestFromHttpRequestLogMutation>;
export type CreateSenderRequestFromHttpRequestLogMutationOptions = Apollo.BaseMutationOptions<CreateSenderRequestFromHttpRequestLogMutation, CreateSenderRequestFromHttpRequestLogMutationVariables>;
export const SendRequestDocument = gql`
    mutation SendRequest($id: ID!) {
  sendRequest(id: $id) {
    id
  }
}
    `;
export type SendRequestMutationFn = Apollo.MutationFunction<SendRequestMutation, SendRequestMutationVariables>;

/**
 * __useSendRequestMutation__
 *
 * To run a mutation, you first call `useSendRequestMutation` within a React component and pass it any options that fit your needs.
 * When your component renders, `useSendRequestMutation` returns a tuple that includes:
 * - A mutate function that you can call at any time to execute the mutation
 * - An object with fields that represent the current status of the mutation's execution
 *
 * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2;
 *
 * @example
 * const [sendRequestMutation, { data, loading, error }] = useSendRequestMutation({
 *   variables: {
 *      id: // value for 'id'
 *   },
 * });
 */
export function useSendRequestMutation(baseOptions?: Apollo.MutationHookOptions<SendRequestMutation, SendRequestMutationVariables>) {
        const options = {...defaultOptions, ...baseOptions}
        return Apollo.useMutation<SendRequestMutation, SendRequestMutationVariables>(SendRequestDocument, options);
      }
export type SendRequestMutationHookResult = ReturnType<typeof useSendRequestMutation>;
export type SendRequestMutationResult = Apollo.MutationResult<SendRequestMutation>;
export type SendRequestMutationOptions = Apollo.BaseMutationOptions<SendRequestMutation, SendRequestMutationVariables>;
export const GetSenderRequestDocument = gql
Download .txt
gitextract_7r6v1eh1/

├── .dockerignore
├── .github/
│   ├── FUNDING.yml
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_report.md
│   │   ├── config.yml
│   │   └── feature_request.md
│   └── workflows/
│       ├── build-test.yml
│       └── lint.yml
├── .gitignore
├── .golangci.yml
├── .goreleaser.yml
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── Dockerfile
├── LICENSE
├── Makefile
├── README.md
├── admin/
│   ├── .eslintrc.json
│   ├── .gitignore
│   ├── .prettierignore
│   ├── .prettierrc.json
│   ├── gqlcodegen.yml
│   ├── next-env.d.ts
│   ├── next.config.js
│   ├── package.json
│   ├── public/
│   │   ├── site.webmanifest
│   │   └── style.css
│   ├── src/
│   │   ├── features/
│   │   │   ├── Layout.tsx
│   │   │   ├── intercept/
│   │   │   │   ├── components/
│   │   │   │   │   ├── EditRequest.tsx
│   │   │   │   │   ├── Intercept.tsx
│   │   │   │   │   └── Requests.tsx
│   │   │   │   └── graphql/
│   │   │   │       ├── cancelRequest.graphql
│   │   │   │       ├── cancelResponse.graphql
│   │   │   │       ├── interceptedRequest.graphql
│   │   │   │       ├── modifyRequest.graphql
│   │   │   │       └── modifyResponse.graphql
│   │   │   ├── projects/
│   │   │   │   ├── components/
│   │   │   │   │   ├── NewProject.tsx
│   │   │   │   │   └── ProjectList.tsx
│   │   │   │   ├── graphql/
│   │   │   │   │   ├── activeProject.graphql
│   │   │   │   │   ├── closeProject.graphql
│   │   │   │   │   ├── createProject.graphql
│   │   │   │   │   ├── deleteProject.graphql
│   │   │   │   │   ├── openProject.graphql
│   │   │   │   │   └── projects.graphql
│   │   │   │   └── hooks/
│   │   │   │       └── useOpenProjectMutation.ts
│   │   │   ├── reqlog/
│   │   │   │   ├── components/
│   │   │   │   │   ├── Actions.tsx
│   │   │   │   │   ├── LogDetail.tsx
│   │   │   │   │   ├── RequestDetail.tsx
│   │   │   │   │   ├── RequestLogs.tsx
│   │   │   │   │   └── Search.tsx
│   │   │   │   ├── graphql/
│   │   │   │   │   ├── clearHttpRequestLog.graphql
│   │   │   │   │   ├── httpRequestLog.graphql
│   │   │   │   │   ├── httpRequestLogFilter.graphql
│   │   │   │   │   ├── httpRequestLogs.graphql
│   │   │   │   │   └── setHttpRequestLogFilter.graphql
│   │   │   │   └── index.ts
│   │   │   ├── scope/
│   │   │   │   ├── components/
│   │   │   │   │   ├── AddRule.tsx
│   │   │   │   │   ├── RuleListItem.tsx
│   │   │   │   │   └── Rules.tsx
│   │   │   │   └── graphql/
│   │   │   │       ├── scope.graphql
│   │   │   │       └── setScope.graphql
│   │   │   ├── sender/
│   │   │   │   ├── components/
│   │   │   │   │   ├── EditRequest.tsx
│   │   │   │   │   ├── History.tsx
│   │   │   │   │   └── Sender.tsx
│   │   │   │   ├── graphql/
│   │   │   │   │   ├── createOrUpdateRequest.graphql
│   │   │   │   │   ├── createSenderRequestFromRequestLog.graphql
│   │   │   │   │   ├── sendRequest.graphql
│   │   │   │   │   ├── senderRequest.graphql
│   │   │   │   │   └── senderRequests.graphql
│   │   │   │   └── index.ts
│   │   │   └── settings/
│   │   │       ├── components/
│   │   │       │   └── Settings.tsx
│   │   │       └── graphql/
│   │   │           └── updateInterceptSettings.graphql
│   │   ├── lib/
│   │   │   ├── ActiveProjectContext.tsx
│   │   │   ├── InterceptedRequestsContext.tsx
│   │   │   ├── components/
│   │   │   │   ├── ConfirmationDialog.tsx
│   │   │   │   ├── Editor.tsx
│   │   │   │   ├── HttpStatusIcon.tsx
│   │   │   │   ├── KeyValuePair.tsx
│   │   │   │   ├── Link.tsx
│   │   │   │   ├── RequestTabs.tsx
│   │   │   │   ├── RequestsTable.tsx
│   │   │   │   ├── Response.tsx
│   │   │   │   ├── ResponseStatus.tsx
│   │   │   │   ├── ResponseTabs.tsx
│   │   │   │   ├── SplitPane.tsx
│   │   │   │   ├── UrlBar.tsx
│   │   │   │   └── useContextMenu.tsx
│   │   │   ├── graphql/
│   │   │   │   ├── generated.tsx
│   │   │   │   ├── interceptedRequests.graphql
│   │   │   │   ├── omitTypename.ts
│   │   │   │   └── useApollo.ts
│   │   │   ├── mui/
│   │   │   │   ├── createEmotionCache.ts
│   │   │   │   └── theme.ts
│   │   │   ├── queryParamsFromURL.tsx
│   │   │   ├── updateKeyPairItem.ts
│   │   │   └── updateURLQueryParams.ts
│   │   ├── pages/
│   │   │   ├── _app.tsx
│   │   │   ├── _document.tsx
│   │   │   ├── index.tsx
│   │   │   ├── projects/
│   │   │   │   └── index.tsx
│   │   │   ├── proxy/
│   │   │   │   ├── index.tsx
│   │   │   │   ├── intercept/
│   │   │   │   │   └── index.tsx
│   │   │   │   └── logs/
│   │   │   │       └── index.tsx
│   │   │   ├── scope/
│   │   │   │   └── index.tsx
│   │   │   ├── sender/
│   │   │   │   └── index.tsx
│   │   │   └── settings/
│   │   │       └── index.tsx
│   │   └── styles.css
│   └── tsconfig.json
├── cmd/
│   └── hetty/
│       ├── cert.go
│       ├── config.go
│       ├── hetty.go
│       └── main.go
├── go.mod
├── go.sum
├── gqlgen.yml
├── pkg/
│   ├── api/
│   │   ├── generated.go
│   │   ├── http.go
│   │   ├── models.go
│   │   ├── models_gen.go
│   │   ├── resolvers.go
│   │   └── schema.graphql
│   ├── chrome/
│   │   └── chrome.go
│   ├── db/
│   │   └── bolt/
│   │       ├── bolt.go
│   │       ├── logger.go
│   │       ├── proj.go
│   │       ├── proj_test.go
│   │       ├── reqlog.go
│   │       ├── reqlog_test.go
│   │       ├── sender.go
│   │       └── sender_test.go
│   ├── filter/
│   │   ├── ast.go
│   │   ├── ast_test.go
│   │   ├── http.go
│   │   ├── lexer.go
│   │   ├── lexer_test.go
│   │   ├── parser.go
│   │   └── parser_test.go
│   ├── log/
│   │   └── log.go
│   ├── proj/
│   │   ├── proj.go
│   │   └── repo.go
│   ├── proxy/
│   │   ├── cert.go
│   │   ├── gzip.go
│   │   ├── intercept/
│   │   │   ├── filter.go
│   │   │   ├── intercept.go
│   │   │   ├── intercept_test.go
│   │   │   └── settings.go
│   │   ├── modify.go
│   │   ├── net.go
│   │   └── proxy.go
│   ├── reqlog/
│   │   ├── repo.go
│   │   ├── reqlog.go
│   │   ├── reqlog_test.go
│   │   ├── search.go
│   │   └── search_test.go
│   ├── scope/
│   │   └── scope.go
│   └── sender/
│       ├── repo.go
│       ├── search.go
│       ├── search_test.go
│       ├── sender.go
│       ├── sender_test.go
│       └── transport.go
└── tools.go
Download .txt
SYMBOL INDEX (1051 symbols across 102 files)

FILE: admin/next.config.js
  method rewrites (line 9) | async rewrites() {

FILE: admin/src/features/Layout.tsx
  type Page (line 35) | enum Page {
  type AppBarProps (line 76) | interface AppBarProps extends MuiAppBarProps {
  type Props (line 135) | interface Props {
  function Layout (line 141) | function Layout({ title, page, children }: Props): JSX.Element {

FILE: admin/src/features/intercept/components/EditRequest.tsx
  function EditRequest (line 29) | function EditRequest(): JSX.Element {

FILE: admin/src/features/intercept/components/Intercept.tsx
  function Sender (line 8) | function Sender(): JSX.Element {

FILE: admin/src/features/intercept/components/Requests.tsx
  function Requests (line 7) | function Requests(): JSX.Element {

FILE: admin/src/features/projects/components/NewProject.tsx
  function NewProject (line 9) | function NewProject(): JSX.Element {

FILE: admin/src/features/projects/components/ProjectList.tsx
  function ProjectList (line 41) | function ProjectList(): JSX.Element {

FILE: admin/src/features/projects/hooks/useOpenProjectMutation.ts
  function useOpenProjectMutation (line 5) | function useOpenProjectMutation() {

FILE: admin/src/features/reqlog/components/Actions.tsx
  function Actions (line 12) | function Actions(): JSX.Element {

FILE: admin/src/features/reqlog/components/LogDetail.tsx
  type Props (line 10) | interface Props {
  function LogDetail (line 14) | function LogDetail({ id }: Props): JSX.Element {

FILE: admin/src/features/reqlog/components/RequestDetail.tsx
  type Props (line 8) | interface Props {
  function RequestDetail (line 12) | function RequestDetail({ request }: Props): JSX.Element {

FILE: admin/src/features/reqlog/components/RequestLogs.tsx
  function RequestLogs (line 31) | function RequestLogs(): JSX.Element {

FILE: admin/src/features/reqlog/components/Search.tsx
  function Search (line 26) | function Search(): JSX.Element {
  function Error (line 162) | function Error(props: { prefix: string; error?: Error }) {

FILE: admin/src/features/scope/components/AddRule.tsx
  function AddRule (line 19) | function AddRule(): JSX.Element {

FILE: admin/src/features/scope/components/RuleListItem.tsx
  type ScopeRule (line 18) | type ScopeRule = ScopeQuery["scope"][number];
  type RuleListItemProps (line 20) | type RuleListItemProps = {
  function RuleListItem (line 26) | function RuleListItem({ scope, rule, index }: RuleListItemProps): JSX.El...
  function RuleListItemText (line 69) | function RuleListItemText({ rule }: { rule: ScopeRule }): JSX.Element {
  function RuleTypeChip (line 81) | function RuleTypeChip({ rule }: { rule: ScopeRule }): JSX.Element {

FILE: admin/src/features/scope/components/Rules.tsx
  function Rules (line 9) | function Rules(): JSX.Element {

FILE: admin/src/features/sender/components/EditRequest.tsx
  function EditRequest (line 25) | function EditRequest(): JSX.Element {

FILE: admin/src/features/sender/components/History.tsx
  function History (line 7) | function History(): JSX.Element {

FILE: admin/src/features/sender/components/Sender.tsx
  function Sender (line 8) | function Sender(): JSX.Element {

FILE: admin/src/features/settings/components/Settings.tsx
  type TabValue (line 28) | enum TabValue {
  function FilterTextField (line 32) | function FilterTextField(props: TextFieldProps): JSX.Element {
  function Settings (line 52) | function Settings(): JSX.Element {

FILE: admin/src/lib/ActiveProjectContext.tsx
  type Props (line 7) | interface Props {
  function ActiveProjectProvider (line 11) | function ActiveProjectProvider({ children }: Props): JSX.Element {
  function useActiveProject (line 18) | function useActiveProject() {

FILE: admin/src/lib/InterceptedRequestsContext.tsx
  type Props (line 7) | interface Props {
  function InterceptedRequestsProvider (line 11) | function InterceptedRequestsProvider({ children }: Props): JSX.Element {
  function useInterceptedRequests (line 20) | function useInterceptedRequests() {

FILE: admin/src/lib/components/ConfirmationDialog.tsx
  function useConfirmationDialog (line 9) | function useConfirmationDialog() {
  type ConfirmationDialog (line 17) | interface ConfirmationDialog {
  function ConfirmationDialog (line 24) | function ConfirmationDialog(props: ConfirmationDialog) {

FILE: admin/src/lib/components/Editor.tsx
  type language (line 11) | type language = "html" | "typescript" | "json";
  function languageForContentType (line 13) | function languageForContentType(contentType?: string): language | undefi...
  type Props (line 29) | interface Props {
  function Editor (line 36) | function Editor({ content, contentType, monacoOptions, onChange }: Props...

FILE: admin/src/lib/components/HttpStatusIcon.tsx
  type Props (line 4) | interface Props {
  function HttpStatusIcon (line 8) | function HttpStatusIcon({ status }: Props): JSX.Element {

FILE: admin/src/lib/components/KeyValuePair.tsx
  type KeyValuePair (line 35) | interface KeyValuePair {
  type KeyValuePairTableProps (line 40) | interface KeyValuePairTableProps {
  function KeyValuePairTable (line 46) | function KeyValuePairTable({ items, onChange, onDelete }: KeyValuePairTa...

FILE: admin/src/lib/components/Link.tsx
  type NextLinkComposedProps (line 11) | interface NextLinkComposedProps
  type LinkProps (line 40) | type LinkProps = {

FILE: admin/src/lib/components/RequestTabs.tsx
  type TabValue (line 9) | enum TabValue {
  type RequestTabsProps (line 15) | interface RequestTabsProps {
  function RequestTabs (line 26) | function RequestTabs(props: RequestTabsProps): JSX.Element {

FILE: admin/src/lib/components/RequestsTable.tsx
  type HttpRequest (line 49) | interface HttpRequest {
  type HttpResponse (line 56) | interface HttpResponse {
  type Props (line 62) | interface Props {
  function RequestsTable (line 70) | function RequestsTable(props: Props): JSX.Element {
  function Status (line 119) | function Status({ code, reason }: { code: number; reason: string }): JSX...

FILE: admin/src/lib/components/Response.tsx
  type ResponseProps (line 8) | interface ResponseProps {
  function Response (line 12) | function Response({ response }: ResponseProps): JSX.Element {

FILE: admin/src/lib/components/ResponseStatus.tsx
  type ResponseStatusProps (line 7) | type ResponseStatusProps = {
  function mapProto (line 13) | function mapProto(proto: HttpProtocol): string {
  function ResponseStatus (line 26) | function ResponseStatus({ proto, statusCode, statusReason }: ResponseSta...

FILE: admin/src/lib/components/ResponseTabs.tsx
  type ResponseTabsProps (line 9) | interface ResponseTabsProps {
  type TabValue (line 18) | enum TabValue {
  function ResponseTabs (line 29) | function ResponseTabs(props: ResponseTabsProps): JSX.Element {

FILE: admin/src/lib/components/SplitPane.tsx
  constant BORDER_WIDTH_FACTOR (line 4) | const BORDER_WIDTH_FACTOR = 1.75;
  constant SIZE_FACTOR (line 5) | const SIZE_FACTOR = 4;
  constant MARGIN_FACTOR (line 6) | const MARGIN_FACTOR = -1.75;

FILE: admin/src/lib/components/UrlBar.tsx
  type HttpMethod (line 5) | enum HttpMethod {
  type HttpProto (line 17) | enum HttpProto {
  type UrlBarProps (line 29) | interface UrlBarProps extends BoxProps {
  function UrlBar (line 38) | function UrlBar(props: UrlBarProps) {

FILE: admin/src/lib/components/useContextMenu.tsx
  type ContextMenuProps (line 4) | interface ContextMenuProps {
  function useContextMenu (line 8) | function useContextMenu(): [

FILE: admin/src/lib/graphql/generated.tsx
  type Maybe (line 3) | type Maybe<T> = T | null;
  type InputMaybe (line 4) | type InputMaybe<T> = Maybe<T>;
  type Exact (line 5) | type Exact<T extends { [key: string]: unknown }> = { [K in keyof T]: T[K...
  type MakeOptional (line 6) | type MakeOptional<T, K extends keyof T> = Omit<T, K> & { [SubKey in K]?:...
  type MakeMaybe (line 7) | type MakeMaybe<T, K extends keyof T> = Omit<T, K> & { [SubKey in K]: May...
  type Scalars (line 10) | type Scalars = {
  type CancelRequestResult (line 21) | type CancelRequestResult = {
  type CancelResponseResult (line 26) | type CancelResponseResult = {
  type ClearHttpRequestLogResult (line 31) | type ClearHttpRequestLogResult = {
  type CloseProjectResult (line 36) | type CloseProjectResult = {
  type DeleteProjectResult (line 41) | type DeleteProjectResult = {
  type DeleteSenderRequestsResult (line 46) | type DeleteSenderRequestsResult = {
  type HttpHeader (line 51) | type HttpHeader = {
  type HttpHeaderInput (line 57) | type HttpHeaderInput = {
  type HttpMethod (line 62) | enum HttpMethod {
  type HttpProtocol (line 74) | enum HttpProtocol {
  type HttpRequest (line 80) | type HttpRequest = {
  type HttpRequestLog (line 91) | type HttpRequestLog = {
  type HttpRequestLogFilter (line 103) | type HttpRequestLogFilter = {
  type HttpRequestLogFilterInput (line 109) | type HttpRequestLogFilterInput = {
  type HttpResponse (line 114) | type HttpResponse = {
  type HttpResponseLog (line 125) | type HttpResponseLog = {
  type InterceptSettings (line 136) | type InterceptSettings = {
  type ModifyRequestInput (line 144) | type ModifyRequestInput = {
  type ModifyRequestResult (line 154) | type ModifyRequestResult = {
  type ModifyResponseInput (line 159) | type ModifyResponseInput = {
  type ModifyResponseResult (line 168) | type ModifyResponseResult = {
  type Mutation (line 173) | type Mutation = {
  type MutationCancelRequestArgs (line 195) | type MutationCancelRequestArgs = {
  type MutationCancelResponseArgs (line 200) | type MutationCancelResponseArgs = {
  type MutationCreateOrUpdateSenderRequestArgs (line 205) | type MutationCreateOrUpdateSenderRequestArgs = {
  type MutationCreateProjectArgs (line 210) | type MutationCreateProjectArgs = {
  type MutationCreateSenderRequestFromHttpRequestLogArgs (line 215) | type MutationCreateSenderRequestFromHttpRequestLogArgs = {
  type MutationDeleteProjectArgs (line 220) | type MutationDeleteProjectArgs = {
  type MutationModifyRequestArgs (line 225) | type MutationModifyRequestArgs = {
  type MutationModifyResponseArgs (line 230) | type MutationModifyResponseArgs = {
  type MutationOpenProjectArgs (line 235) | type MutationOpenProjectArgs = {
  type MutationSendRequestArgs (line 240) | type MutationSendRequestArgs = {
  type MutationSetHttpRequestLogFilterArgs (line 245) | type MutationSetHttpRequestLogFilterArgs = {
  type MutationSetScopeArgs (line 250) | type MutationSetScopeArgs = {
  type MutationSetSenderRequestFilterArgs (line 255) | type MutationSetSenderRequestFilterArgs = {
  type MutationUpdateInterceptSettingsArgs (line 260) | type MutationUpdateInterceptSettingsArgs = {
  type Project (line 264) | type Project = {
  type ProjectSettings (line 272) | type ProjectSettings = {
  type Query (line 277) | type Query = {
  type QueryHttpRequestLogArgs (line 292) | type QueryHttpRequestLogArgs = {
  type QueryInterceptedRequestArgs (line 297) | type QueryInterceptedRequestArgs = {
  type QuerySenderRequestArgs (line 302) | type QuerySenderRequestArgs = {
  type ScopeHeader (line 306) | type ScopeHeader = {
  type ScopeHeaderInput (line 312) | type ScopeHeaderInput = {
  type ScopeRule (line 317) | type ScopeRule = {
  type ScopeRuleInput (line 324) | type ScopeRuleInput = {
  type SenderRequest (line 330) | type SenderRequest = {
  type SenderRequestFilter (line 343) | type SenderRequestFilter = {
  type SenderRequestFilterInput (line 349) | type SenderRequestFilterInput = {
  type SenderRequestInput (line 354) | type SenderRequestInput = {
  type UpdateInterceptSettingsInput (line 363) | type UpdateInterceptSettingsInput = {
  type CancelRequestMutationVariables (line 370) | type CancelRequestMutationVariables = Exact<{
  type CancelRequestMutation (line 375) | type CancelRequestMutation = { __typename?: 'Mutation', cancelRequest: {...
  type CancelResponseMutationVariables (line 377) | type CancelResponseMutationVariables = Exact<{
  type CancelResponseMutation (line 382) | type CancelResponseMutation = { __typename?: 'Mutation', cancelResponse:...
  type GetInterceptedRequestQueryVariables (line 384) | type GetInterceptedRequestQueryVariables = Exact<{
  type GetInterceptedRequestQuery (line 389) | type GetInterceptedRequestQuery = { __typename?: 'Query', interceptedReq...
  type ModifyRequestMutationVariables (line 391) | type ModifyRequestMutationVariables = Exact<{
  type ModifyRequestMutation (line 396) | type ModifyRequestMutation = { __typename?: 'Mutation', modifyRequest: {...
  type ModifyResponseMutationVariables (line 398) | type ModifyResponseMutationVariables = Exact<{
  type ModifyResponseMutation (line 403) | type ModifyResponseMutation = { __typename?: 'Mutation', modifyResponse:...
  type ActiveProjectQueryVariables (line 405) | type ActiveProjectQueryVariables = Exact<{ [key: string]: never; }>;
  type ActiveProjectQuery (line 408) | type ActiveProjectQuery = { __typename?: 'Query', activeProject?: { __ty...
  type CloseProjectMutationVariables (line 410) | type CloseProjectMutationVariables = Exact<{ [key: string]: never; }>;
  type CloseProjectMutation (line 413) | type CloseProjectMutation = { __typename?: 'Mutation', closeProject: { _...
  type CreateProjectMutationVariables (line 415) | type CreateProjectMutationVariables = Exact<{
  type CreateProjectMutation (line 420) | type CreateProjectMutation = { __typename?: 'Mutation', createProject?: ...
  type DeleteProjectMutationVariables (line 422) | type DeleteProjectMutationVariables = Exact<{
  type DeleteProjectMutation (line 427) | type DeleteProjectMutation = { __typename?: 'Mutation', deleteProject: {...
  type OpenProjectMutationVariables (line 429) | type OpenProjectMutationVariables = Exact<{
  type OpenProjectMutation (line 434) | type OpenProjectMutation = { __typename?: 'Mutation', openProject?: { __...
  type ProjectsQueryVariables (line 436) | type ProjectsQueryVariables = Exact<{ [key: string]: never; }>;
  type ProjectsQuery (line 439) | type ProjectsQuery = { __typename?: 'Query', projects: Array<{ __typenam...
  type ClearHttpRequestLogMutationVariables (line 441) | type ClearHttpRequestLogMutationVariables = Exact<{ [key: string]: never...
  type ClearHttpRequestLogMutation (line 444) | type ClearHttpRequestLogMutation = { __typename?: 'Mutation', clearHTTPR...
  type HttpRequestLogQueryVariables (line 446) | type HttpRequestLogQueryVariables = Exact<{
  type HttpRequestLogQuery (line 451) | type HttpRequestLogQuery = { __typename?: 'Query', httpRequestLog?: { __...
  type HttpRequestLogFilterQueryVariables (line 453) | type HttpRequestLogFilterQueryVariables = Exact<{ [key: string]: never; }>;
  type HttpRequestLogFilterQuery (line 456) | type HttpRequestLogFilterQuery = { __typename?: 'Query', httpRequestLogF...
  type HttpRequestLogsQueryVariables (line 458) | type HttpRequestLogsQueryVariables = Exact<{ [key: string]: never; }>;
  type HttpRequestLogsQuery (line 461) | type HttpRequestLogsQuery = { __typename?: 'Query', httpRequestLogs: Arr...
  type SetHttpRequestLogFilterMutationVariables (line 463) | type SetHttpRequestLogFilterMutationVariables = Exact<{
  type SetHttpRequestLogFilterMutation (line 468) | type SetHttpRequestLogFilterMutation = { __typename?: 'Mutation', setHtt...
  type ScopeQueryVariables (line 470) | type ScopeQueryVariables = Exact<{ [key: string]: never; }>;
  type ScopeQuery (line 473) | type ScopeQuery = { __typename?: 'Query', scope: Array<{ __typename?: 'S...
  type SetScopeMutationVariables (line 475) | type SetScopeMutationVariables = Exact<{
  type SetScopeMutation (line 480) | type SetScopeMutation = { __typename?: 'Mutation', setScope: Array<{ __t...
  type CreateOrUpdateSenderRequestMutationVariables (line 482) | type CreateOrUpdateSenderRequestMutationVariables = Exact<{
  type CreateOrUpdateSenderRequestMutation (line 487) | type CreateOrUpdateSenderRequestMutation = { __typename?: 'Mutation', cr...
  type CreateSenderRequestFromHttpRequestLogMutationVariables (line 489) | type CreateSenderRequestFromHttpRequestLogMutationVariables = Exact<{
  type CreateSenderRequestFromHttpRequestLogMutation (line 494) | type CreateSenderRequestFromHttpRequestLogMutation = { __typename?: 'Mut...
  type SendRequestMutationVariables (line 496) | type SendRequestMutationVariables = Exact<{
  type SendRequestMutation (line 501) | type SendRequestMutation = { __typename?: 'Mutation', sendRequest: { __t...
  type GetSenderRequestQueryVariables (line 503) | type GetSenderRequestQueryVariables = Exact<{
  type GetSenderRequestQuery (line 508) | type GetSenderRequestQuery = { __typename?: 'Query', senderRequest?: { _...
  type GetSenderRequestsQueryVariables (line 510) | type GetSenderRequestsQueryVariables = Exact<{ [key: string]: never; }>;
  type GetSenderRequestsQuery (line 513) | type GetSenderRequestsQuery = { __typename?: 'Query', senderRequests: Ar...
  type UpdateInterceptSettingsMutationVariables (line 515) | type UpdateInterceptSettingsMutationVariables = Exact<{
  type UpdateInterceptSettingsMutation (line 520) | type UpdateInterceptSettingsMutation = { __typename?: 'Mutation', update...
  type GetInterceptedRequestsQueryVariables (line 522) | type GetInterceptedRequestsQueryVariables = Exact<{ [key: string]: never...
  type GetInterceptedRequestsQuery (line 525) | type GetInterceptedRequestsQuery = { __typename?: 'Query', interceptedRe...
  type CancelRequestMutationFn (line 535) | type CancelRequestMutationFn = Apollo.MutationFunction<CancelRequestMuta...
  function useCancelRequestMutation (line 554) | function useCancelRequestMutation(baseOptions?: Apollo.MutationHookOptio...
  type CancelRequestMutationHookResult (line 558) | type CancelRequestMutationHookResult = ReturnType<typeof useCancelReques...
  type CancelRequestMutationResult (line 559) | type CancelRequestMutationResult = Apollo.MutationResult<CancelRequestMu...
  type CancelRequestMutationOptions (line 560) | type CancelRequestMutationOptions = Apollo.BaseMutationOptions<CancelReq...
  type CancelResponseMutationFn (line 568) | type CancelResponseMutationFn = Apollo.MutationFunction<CancelResponseMu...
  function useCancelResponseMutation (line 587) | function useCancelResponseMutation(baseOptions?: Apollo.MutationHookOpti...
  type CancelResponseMutationHookResult (line 591) | type CancelResponseMutationHookResult = ReturnType<typeof useCancelRespo...
  type CancelResponseMutationResult (line 592) | type CancelResponseMutationResult = Apollo.MutationResult<CancelResponse...
  type CancelResponseMutationOptions (line 593) | type CancelResponseMutationOptions = Apollo.BaseMutationOptions<CancelRe...
  function useGetInterceptedRequestQuery (line 637) | function useGetInterceptedRequestQuery(baseOptions: Apollo.QueryHookOpti...
  function useGetInterceptedRequestLazyQuery (line 641) | function useGetInterceptedRequestLazyQuery(baseOptions?: Apollo.LazyQuer...
  type GetInterceptedRequestQueryHookResult (line 645) | type GetInterceptedRequestQueryHookResult = ReturnType<typeof useGetInte...
  type GetInterceptedRequestLazyQueryHookResult (line 646) | type GetInterceptedRequestLazyQueryHookResult = ReturnType<typeof useGet...
  type GetInterceptedRequestQueryResult (line 647) | type GetInterceptedRequestQueryResult = Apollo.QueryResult<GetIntercepte...
  type ModifyRequestMutationFn (line 655) | type ModifyRequestMutationFn = Apollo.MutationFunction<ModifyRequestMuta...
  function useModifyRequestMutation (line 674) | function useModifyRequestMutation(baseOptions?: Apollo.MutationHookOptio...
  type ModifyRequestMutationHookResult (line 678) | type ModifyRequestMutationHookResult = ReturnType<typeof useModifyReques...
  type ModifyRequestMutationResult (line 679) | type ModifyRequestMutationResult = Apollo.MutationResult<ModifyRequestMu...
  type ModifyRequestMutationOptions (line 680) | type ModifyRequestMutationOptions = Apollo.BaseMutationOptions<ModifyReq...
  type ModifyResponseMutationFn (line 688) | type ModifyResponseMutationFn = Apollo.MutationFunction<ModifyResponseMu...
  function useModifyResponseMutation (line 707) | function useModifyResponseMutation(baseOptions?: Apollo.MutationHookOpti...
  type ModifyResponseMutationHookResult (line 711) | type ModifyResponseMutationHookResult = ReturnType<typeof useModifyRespo...
  type ModifyResponseMutationResult (line 712) | type ModifyResponseMutationResult = Apollo.MutationResult<ModifyResponse...
  type ModifyResponseMutationOptions (line 713) | type ModifyResponseMutationOptions = Apollo.BaseMutationOptions<ModifyRe...
  function useActiveProjectQuery (line 747) | function useActiveProjectQuery(baseOptions?: Apollo.QueryHookOptions<Act...
  function useActiveProjectLazyQuery (line 751) | function useActiveProjectLazyQuery(baseOptions?: Apollo.LazyQueryHookOpt...
  type ActiveProjectQueryHookResult (line 755) | type ActiveProjectQueryHookResult = ReturnType<typeof useActiveProjectQu...
  type ActiveProjectLazyQueryHookResult (line 756) | type ActiveProjectLazyQueryHookResult = ReturnType<typeof useActiveProje...
  type ActiveProjectQueryResult (line 757) | type ActiveProjectQueryResult = Apollo.QueryResult<ActiveProjectQuery, A...
  type CloseProjectMutationFn (line 765) | type CloseProjectMutationFn = Apollo.MutationFunction<CloseProjectMutati...
  function useCloseProjectMutation (line 783) | function useCloseProjectMutation(baseOptions?: Apollo.MutationHookOption...
  type CloseProjectMutationHookResult (line 787) | type CloseProjectMutationHookResult = ReturnType<typeof useCloseProjectM...
  type CloseProjectMutationResult (line 788) | type CloseProjectMutationResult = Apollo.MutationResult<CloseProjectMuta...
  type CloseProjectMutationOptions (line 789) | type CloseProjectMutationOptions = Apollo.BaseMutationOptions<CloseProje...
  type CreateProjectMutationFn (line 798) | type CreateProjectMutationFn = Apollo.MutationFunction<CreateProjectMuta...
  function useCreateProjectMutation (line 817) | function useCreateProjectMutation(baseOptions?: Apollo.MutationHookOptio...
  type CreateProjectMutationHookResult (line 821) | type CreateProjectMutationHookResult = ReturnType<typeof useCreateProjec...
  type CreateProjectMutationResult (line 822) | type CreateProjectMutationResult = Apollo.MutationResult<CreateProjectMu...
  type CreateProjectMutationOptions (line 823) | type CreateProjectMutationOptions = Apollo.BaseMutationOptions<CreatePro...
  type DeleteProjectMutationFn (line 831) | type DeleteProjectMutationFn = Apollo.MutationFunction<DeleteProjectMuta...
  function useDeleteProjectMutation (line 850) | function useDeleteProjectMutation(baseOptions?: Apollo.MutationHookOptio...
  type DeleteProjectMutationHookResult (line 854) | type DeleteProjectMutationHookResult = ReturnType<typeof useDeleteProjec...
  type DeleteProjectMutationResult (line 855) | type DeleteProjectMutationResult = Apollo.MutationResult<DeleteProjectMu...
  type DeleteProjectMutationOptions (line 856) | type DeleteProjectMutationOptions = Apollo.BaseMutationOptions<DeletePro...
  type OpenProjectMutationFn (line 866) | type OpenProjectMutationFn = Apollo.MutationFunction<OpenProjectMutation...
  function useOpenProjectMutation (line 885) | function useOpenProjectMutation(baseOptions?: Apollo.MutationHookOptions...
  type OpenProjectMutationHookResult (line 889) | type OpenProjectMutationHookResult = ReturnType<typeof useOpenProjectMut...
  type OpenProjectMutationResult (line 890) | type OpenProjectMutationResult = Apollo.MutationResult<OpenProjectMutati...
  type OpenProjectMutationOptions (line 891) | type OpenProjectMutationOptions = Apollo.BaseMutationOptions<OpenProject...
  function useProjectsQuery (line 917) | function useProjectsQuery(baseOptions?: Apollo.QueryHookOptions<Projects...
  function useProjectsLazyQuery (line 921) | function useProjectsLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<...
  type ProjectsQueryHookResult (line 925) | type ProjectsQueryHookResult = ReturnType<typeof useProjectsQuery>;
  type ProjectsLazyQueryHookResult (line 926) | type ProjectsLazyQueryHookResult = ReturnType<typeof useProjectsLazyQuery>;
  type ProjectsQueryResult (line 927) | type ProjectsQueryResult = Apollo.QueryResult<ProjectsQuery, ProjectsQue...
  type ClearHttpRequestLogMutationFn (line 935) | type ClearHttpRequestLogMutationFn = Apollo.MutationFunction<ClearHttpRe...
  function useClearHttpRequestLogMutation (line 953) | function useClearHttpRequestLogMutation(baseOptions?: Apollo.MutationHoo...
  type ClearHttpRequestLogMutationHookResult (line 957) | type ClearHttpRequestLogMutationHookResult = ReturnType<typeof useClearH...
  type ClearHttpRequestLogMutationResult (line 958) | type ClearHttpRequestLogMutationResult = Apollo.MutationResult<ClearHttp...
  type ClearHttpRequestLogMutationOptions (line 959) | type ClearHttpRequestLogMutationOptions = Apollo.BaseMutationOptions<Cle...
  function useHttpRequestLogQuery (line 1003) | function useHttpRequestLogQuery(baseOptions: Apollo.QueryHookOptions<Htt...
  function useHttpRequestLogLazyQuery (line 1007) | function useHttpRequestLogLazyQuery(baseOptions?: Apollo.LazyQueryHookOp...
  type HttpRequestLogQueryHookResult (line 1011) | type HttpRequestLogQueryHookResult = ReturnType<typeof useHttpRequestLog...
  type HttpRequestLogLazyQueryHookResult (line 1012) | type HttpRequestLogLazyQueryHookResult = ReturnType<typeof useHttpReques...
  type HttpRequestLogQueryResult (line 1013) | type HttpRequestLogQueryResult = Apollo.QueryResult<HttpRequestLogQuery,...
  function useHttpRequestLogFilterQuery (line 1038) | function useHttpRequestLogFilterQuery(baseOptions?: Apollo.QueryHookOpti...
  function useHttpRequestLogFilterLazyQuery (line 1042) | function useHttpRequestLogFilterLazyQuery(baseOptions?: Apollo.LazyQuery...
  type HttpRequestLogFilterQueryHookResult (line 1046) | type HttpRequestLogFilterQueryHookResult = ReturnType<typeof useHttpRequ...
  type HttpRequestLogFilterLazyQueryHookResult (line 1047) | type HttpRequestLogFilterLazyQueryHookResult = ReturnType<typeof useHttp...
  type HttpRequestLogFilterQueryResult (line 1048) | type HttpRequestLogFilterQueryResult = Apollo.QueryResult<HttpRequestLog...
  function useHttpRequestLogsQuery (line 1079) | function useHttpRequestLogsQuery(baseOptions?: Apollo.QueryHookOptions<H...
  function useHttpRequestLogsLazyQuery (line 1083) | function useHttpRequestLogsLazyQuery(baseOptions?: Apollo.LazyQueryHookO...
  type HttpRequestLogsQueryHookResult (line 1087) | type HttpRequestLogsQueryHookResult = ReturnType<typeof useHttpRequestLo...
  type HttpRequestLogsLazyQueryHookResult (line 1088) | type HttpRequestLogsLazyQueryHookResult = ReturnType<typeof useHttpReque...
  type HttpRequestLogsQueryResult (line 1089) | type HttpRequestLogsQueryResult = Apollo.QueryResult<HttpRequestLogsQuer...
  type SetHttpRequestLogFilterMutationFn (line 1098) | type SetHttpRequestLogFilterMutationFn = Apollo.MutationFunction<SetHttp...
  function useSetHttpRequestLogFilterMutation (line 1117) | function useSetHttpRequestLogFilterMutation(baseOptions?: Apollo.Mutatio...
  type SetHttpRequestLogFilterMutationHookResult (line 1121) | type SetHttpRequestLogFilterMutationHookResult = ReturnType<typeof useSe...
  type SetHttpRequestLogFilterMutationResult (line 1122) | type SetHttpRequestLogFilterMutationResult = Apollo.MutationResult<SetHt...
  type SetHttpRequestLogFilterMutationOptions (line 1123) | type SetHttpRequestLogFilterMutationOptions = Apollo.BaseMutationOptions...
  function useScopeQuery (line 1147) | function useScopeQuery(baseOptions?: Apollo.QueryHookOptions<ScopeQuery,...
  function useScopeLazyQuery (line 1151) | function useScopeLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<Sco...
  type ScopeQueryHookResult (line 1155) | type ScopeQueryHookResult = ReturnType<typeof useScopeQuery>;
  type ScopeLazyQueryHookResult (line 1156) | type ScopeLazyQueryHookResult = ReturnType<typeof useScopeLazyQuery>;
  type ScopeQueryResult (line 1157) | type ScopeQueryResult = Apollo.QueryResult<ScopeQuery, ScopeQueryVariabl...
  type SetScopeMutationFn (line 1165) | type SetScopeMutationFn = Apollo.MutationFunction<SetScopeMutation, SetS...
  function useSetScopeMutation (line 1184) | function useSetScopeMutation(baseOptions?: Apollo.MutationHookOptions<Se...
  type SetScopeMutationHookResult (line 1188) | type SetScopeMutationHookResult = ReturnType<typeof useSetScopeMutation>;
  type SetScopeMutationResult (line 1189) | type SetScopeMutationResult = Apollo.MutationResult<SetScopeMutation>;
  type SetScopeMutationOptions (line 1190) | type SetScopeMutationOptions = Apollo.BaseMutationOptions<SetScopeMutati...
  type CreateOrUpdateSenderRequestMutationFn (line 1198) | type CreateOrUpdateSenderRequestMutationFn = Apollo.MutationFunction<Cre...
  function useCreateOrUpdateSenderRequestMutation (line 1217) | function useCreateOrUpdateSenderRequestMutation(baseOptions?: Apollo.Mut...
  type CreateOrUpdateSenderRequestMutationHookResult (line 1221) | type CreateOrUpdateSenderRequestMutationHookResult = ReturnType<typeof u...
  type CreateOrUpdateSenderRequestMutationResult (line 1222) | type CreateOrUpdateSenderRequestMutationResult = Apollo.MutationResult<C...
  type CreateOrUpdateSenderRequestMutationOptions (line 1223) | type CreateOrUpdateSenderRequestMutationOptions = Apollo.BaseMutationOpt...
  type CreateSenderRequestFromHttpRequestLogMutationFn (line 1231) | type CreateSenderRequestFromHttpRequestLogMutationFn = Apollo.MutationFu...
  function useCreateSenderRequestFromHttpRequestLogMutation (line 1250) | function useCreateSenderRequestFromHttpRequestLogMutation(baseOptions?: ...
  type CreateSenderRequestFromHttpRequestLogMutationHookResult (line 1254) | type CreateSenderRequestFromHttpRequestLogMutationHookResult = ReturnTyp...
  type CreateSenderRequestFromHttpRequestLogMutationResult (line 1255) | type CreateSenderRequestFromHttpRequestLogMutationResult = Apollo.Mutati...
  type CreateSenderRequestFromHttpRequestLogMutationOptions (line 1256) | type CreateSenderRequestFromHttpRequestLogMutationOptions = Apollo.BaseM...
  type SendRequestMutationFn (line 1264) | type SendRequestMutationFn = Apollo.MutationFunction<SendRequestMutation...
  function useSendRequestMutation (line 1283) | function useSendRequestMutation(baseOptions?: Apollo.MutationHookOptions...
  type SendRequestMutationHookResult (line 1287) | type SendRequestMutationHookResult = ReturnType<typeof useSendRequestMut...
  type SendRequestMutationResult (line 1288) | type SendRequestMutationResult = Apollo.MutationResult<SendRequestMutati...
  type SendRequestMutationOptions (line 1289) | type SendRequestMutationOptions = Apollo.BaseMutationOptions<SendRequest...
  function useGetSenderRequestQuery (line 1335) | function useGetSenderRequestQuery(baseOptions: Apollo.QueryHookOptions<G...
  function useGetSenderRequestLazyQuery (line 1339) | function useGetSenderRequestLazyQuery(baseOptions?: Apollo.LazyQueryHook...
  type GetSenderRequestQueryHookResult (line 1343) | type GetSenderRequestQueryHookResult = ReturnType<typeof useGetSenderReq...
  type GetSenderRequestLazyQueryHookResult (line 1344) | type GetSenderRequestLazyQueryHookResult = ReturnType<typeof useGetSende...
  type GetSenderRequestQueryResult (line 1345) | type GetSenderRequestQueryResult = Apollo.QueryResult<GetSenderRequestQu...
  function useGetSenderRequestsQuery (line 1376) | function useGetSenderRequestsQuery(baseOptions?: Apollo.QueryHookOptions...
  function useGetSenderRequestsLazyQuery (line 1380) | function useGetSenderRequestsLazyQuery(baseOptions?: Apollo.LazyQueryHoo...
  type GetSenderRequestsQueryHookResult (line 1384) | type GetSenderRequestsQueryHookResult = ReturnType<typeof useGetSenderRe...
  type GetSenderRequestsLazyQueryHookResult (line 1385) | type GetSenderRequestsLazyQueryHookResult = ReturnType<typeof useGetSend...
  type GetSenderRequestsQueryResult (line 1386) | type GetSenderRequestsQueryResult = Apollo.QueryResult<GetSenderRequests...
  type UpdateInterceptSettingsMutationFn (line 1397) | type UpdateInterceptSettingsMutationFn = Apollo.MutationFunction<UpdateI...
  function useUpdateInterceptSettingsMutation (line 1416) | function useUpdateInterceptSettingsMutation(baseOptions?: Apollo.Mutatio...
  type UpdateInterceptSettingsMutationHookResult (line 1420) | type UpdateInterceptSettingsMutationHookResult = ReturnType<typeof useUp...
  type UpdateInterceptSettingsMutationResult (line 1421) | type UpdateInterceptSettingsMutationResult = Apollo.MutationResult<Updat...
  type UpdateInterceptSettingsMutationOptions (line 1422) | type UpdateInterceptSettingsMutationOptions = Apollo.BaseMutationOptions...
  function useGetInterceptedRequestsQuery (line 1452) | function useGetInterceptedRequestsQuery(baseOptions?: Apollo.QueryHookOp...
  function useGetInterceptedRequestsLazyQuery (line 1456) | function useGetInterceptedRequestsLazyQuery(baseOptions?: Apollo.LazyQue...
  type GetInterceptedRequestsQueryHookResult (line 1460) | type GetInterceptedRequestsQueryHookResult = ReturnType<typeof useGetInt...
  type GetInterceptedRequestsLazyQueryHookResult (line 1461) | type GetInterceptedRequestsLazyQueryHookResult = ReturnType<typeof useGe...
  type GetInterceptedRequestsQueryResult (line 1462) | type GetInterceptedRequestsQueryResult = Apollo.QueryResult<GetIntercept...

FILE: admin/src/lib/graphql/omitTypename.ts
  function omitTypename (line 1) | function omitTypename<T>(key: string, value: T): T | undefined {
  function withoutTypename (line 5) | function withoutTypename<T>(input: T): T {

FILE: admin/src/lib/graphql/useApollo.ts
  function createApolloClient (line 5) | function createApolloClient() {
  function useApollo (line 30) | function useApollo() {

FILE: admin/src/lib/mui/createEmotionCache.ts
  function createEmotionCache (line 5) | function createEmotionCache() {

FILE: admin/src/lib/mui/theme.ts
  type PaperPropsVariantOverrides (line 5) | interface PaperPropsVariantOverrides {

FILE: admin/src/lib/queryParamsFromURL.tsx
  function queryParamsFromURL (line 3) | function queryParamsFromURL(url: string): KeyValuePair[] {

FILE: admin/src/lib/updateKeyPairItem.ts
  function updateKeyPairItem (line 3) | function updateKeyPairItem(key: string, value: string, idx: number, item...

FILE: admin/src/lib/updateURLQueryParams.ts
  function updateURLQueryParams (line 3) | function updateURLQueryParams(url: string, queryParams: KeyValuePair[]) {

FILE: admin/src/pages/_app.tsx
  type MyAppProps (line 20) | interface MyAppProps extends AppProps {
  function MyApp (line 24) | function MyApp(props: MyAppProps) {

FILE: admin/src/pages/_document.tsx
  class MyDocument (line 8) | class MyDocument extends Document {
    method render (line 10) | render() {

FILE: admin/src/pages/index.tsx
  function Index (line 7) | function Index(): JSX.Element {

FILE: admin/src/pages/projects/index.tsx
  function Index (line 7) | function Index(): JSX.Element {

FILE: admin/src/pages/proxy/index.tsx
  function Index (line 8) | function Index(): JSX.Element {

FILE: admin/src/pages/proxy/intercept/index.tsx
  function ProxyIntercept (line 4) | function ProxyIntercept(): JSX.Element {

FILE: admin/src/pages/proxy/logs/index.tsx
  function ProxyLogs (line 4) | function ProxyLogs(): JSX.Element {

FILE: admin/src/pages/scope/index.tsx
  function Index (line 8) | function Index(): JSX.Element {

FILE: admin/src/pages/sender/index.tsx
  function Index (line 4) | function Index(): JSX.Element {

FILE: admin/src/pages/settings/index.tsx
  function Index (line 4) | function Index(): JSX.Element {

FILE: cmd/hetty/cert.go
  type CertInstallCommand (line 67) | type CertInstallCommand struct
    method Exec (line 122) | func (cmd *CertInstallCommand) Exec(_ context.Context, _ []string) err...
  type CertUninstallCommand (line 75) | type CertUninstallCommand struct
    method Exec (line 180) | func (cmd *CertUninstallCommand) Exec(_ context.Context, _ []string) e...
  function NewCertCommand (line 83) | func NewCertCommand(rootConfig *Config) *ffcli.Command {
  function NewCertInstallCommand (line 99) | func NewCertInstallCommand(rootConfig *Config) *ffcli.Command {
  function NewCertUninstallCommand (line 156) | func NewCertUninstallCommand(rootConfig *Config) *ffcli.Command {

FILE: cmd/hetty/config.go
  type Config (line 10) | type Config struct
    method RegisterFlags (line 20) | func (cfg *Config) RegisterFlags(fs *flag.FlagSet) {

FILE: cmd/hetty/hetty.go
  type HettyCommand (line 69) | type HettyCommand struct
    method Exec (line 112) | func (cmd *HettyCommand) Exec(ctx context.Context, _ []string) error {
  function NewHettyCommand (line 80) | func NewHettyCommand() (*ffcli.Command, *Config) {

FILE: cmd/hetty/main.go
  function main (line 15) | func main() {

FILE: pkg/api/generated.go
  function NewExecutableSchema (line 25) | func NewExecutableSchema(cfg Config) graphql.ExecutableSchema {
  type Config (line 33) | type Config struct
  type ResolverRoot (line 39) | type ResolverRoot interface
  type DirectiveRoot (line 44) | type DirectiveRoot struct
  type ComplexityRoot (line 47) | type ComplexityRoot struct
  type MutationResolver (line 209) | type MutationResolver interface
  type QueryResolver (line 228) | type QueryResolver interface
  type executableSchema (line 241) | type executableSchema struct
    method Schema (line 247) | func (e *executableSchema) Schema() *ast.Schema {
    method Complexity (line 251) | func (e *executableSchema) Complexity(typeName, field string, childCom...
    method Exec (line 982) | func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseH...
  type executionContext (line 1022) | type executionContext struct
    method introspectSchema (line 1027) | func (ec *executionContext) introspectSchema() (*introspection.Schema,...
    method introspectType (line 1034) | func (ec *executionContext) introspectType(name string) (*introspectio...
    method field_Mutation_cancelRequest_args (line 1302) | func (ec *executionContext) field_Mutation_cancelRequest_args(ctx cont...
    method field_Mutation_cancelResponse_args (line 1317) | func (ec *executionContext) field_Mutation_cancelResponse_args(ctx con...
    method field_Mutation_createOrUpdateSenderRequest_args (line 1332) | func (ec *executionContext) field_Mutation_createOrUpdateSenderRequest...
    method field_Mutation_createProject_args (line 1347) | func (ec *executionContext) field_Mutation_createProject_args(ctx cont...
    method field_Mutation_createSenderRequestFromHttpRequestLog_args (line 1362) | func (ec *executionContext) field_Mutation_createSenderRequestFromHttp...
    method field_Mutation_deleteProject_args (line 1377) | func (ec *executionContext) field_Mutation_deleteProject_args(ctx cont...
    method field_Mutation_modifyRequest_args (line 1392) | func (ec *executionContext) field_Mutation_modifyRequest_args(ctx cont...
    method field_Mutation_modifyResponse_args (line 1407) | func (ec *executionContext) field_Mutation_modifyResponse_args(ctx con...
    method field_Mutation_openProject_args (line 1422) | func (ec *executionContext) field_Mutation_openProject_args(ctx contex...
    method field_Mutation_sendRequest_args (line 1437) | func (ec *executionContext) field_Mutation_sendRequest_args(ctx contex...
    method field_Mutation_setHttpRequestLogFilter_args (line 1452) | func (ec *executionContext) field_Mutation_setHttpRequestLogFilter_arg...
    method field_Mutation_setScope_args (line 1467) | func (ec *executionContext) field_Mutation_setScope_args(ctx context.C...
    method field_Mutation_setSenderRequestFilter_args (line 1482) | func (ec *executionContext) field_Mutation_setSenderRequestFilter_args...
    method field_Mutation_updateInterceptSettings_args (line 1497) | func (ec *executionContext) field_Mutation_updateInterceptSettings_arg...
    method field_Query___type_args (line 1512) | func (ec *executionContext) field_Query___type_args(ctx context.Contex...
    method field_Query_httpRequestLog_args (line 1527) | func (ec *executionContext) field_Query_httpRequestLog_args(ctx contex...
    method field_Query_interceptedRequest_args (line 1542) | func (ec *executionContext) field_Query_interceptedRequest_args(ctx co...
    method field_Query_senderRequest_args (line 1557) | func (ec *executionContext) field_Query_senderRequest_args(ctx context...
    method field___Type_enumValues_args (line 1572) | func (ec *executionContext) field___Type_enumValues_args(ctx context.C...
    method field___Type_fields_args (line 1587) | func (ec *executionContext) field___Type_fields_args(ctx context.Conte...
    method _CancelRequestResult_success (line 1610) | func (ec *executionContext) _CancelRequestResult_success(ctx context.C...
    method _CancelResponseResult_success (line 1645) | func (ec *executionContext) _CancelResponseResult_success(ctx context....
    method _ClearHTTPRequestLogResult_success (line 1680) | func (ec *executionContext) _ClearHTTPRequestLogResult_success(ctx con...
    method _CloseProjectResult_success (line 1715) | func (ec *executionContext) _CloseProjectResult_success(ctx context.Co...
    method _DeleteProjectResult_success (line 1750) | func (ec *executionContext) _DeleteProjectResult_success(ctx context.C...
    method _DeleteSenderRequestsResult_success (line 1785) | func (ec *executionContext) _DeleteSenderRequestsResult_success(ctx co...
    method _HttpHeader_key (line 1820) | func (ec *executionContext) _HttpHeader_key(ctx context.Context, field...
    method _HttpHeader_value (line 1855) | func (ec *executionContext) _HttpHeader_value(ctx context.Context, fie...
    method _HttpRequest_id (line 1890) | func (ec *executionContext) _HttpRequest_id(ctx context.Context, field...
    method _HttpRequest_url (line 1925) | func (ec *executionContext) _HttpRequest_url(ctx context.Context, fiel...
    method _HttpRequest_method (line 1960) | func (ec *executionContext) _HttpRequest_method(ctx context.Context, f...
    method _HttpRequest_proto (line 1995) | func (ec *executionContext) _HttpRequest_proto(ctx context.Context, fi...
    method _HttpRequest_headers (line 2030) | func (ec *executionContext) _HttpRequest_headers(ctx context.Context, ...
    method _HttpRequest_body (line 2065) | func (ec *executionContext) _HttpRequest_body(ctx context.Context, fie...
    method _HttpRequest_response (line 2097) | func (ec *executionContext) _HttpRequest_response(ctx context.Context,...
    method _HttpRequestLog_id (line 2129) | func (ec *executionContext) _HttpRequestLog_id(ctx context.Context, fi...
    method _HttpRequestLog_url (line 2164) | func (ec *executionContext) _HttpRequestLog_url(ctx context.Context, f...
    method _HttpRequestLog_method (line 2199) | func (ec *executionContext) _HttpRequestLog_method(ctx context.Context...
    method _HttpRequestLog_proto (line 2234) | func (ec *executionContext) _HttpRequestLog_proto(ctx context.Context,...
    method _HttpRequestLog_headers (line 2269) | func (ec *executionContext) _HttpRequestLog_headers(ctx context.Contex...
    method _HttpRequestLog_body (line 2304) | func (ec *executionContext) _HttpRequestLog_body(ctx context.Context, ...
    method _HttpRequestLog_timestamp (line 2336) | func (ec *executionContext) _HttpRequestLog_timestamp(ctx context.Cont...
    method _HttpRequestLog_response (line 2371) | func (ec *executionContext) _HttpRequestLog_response(ctx context.Conte...
    method _HttpRequestLogFilter_onlyInScope (line 2403) | func (ec *executionContext) _HttpRequestLogFilter_onlyInScope(ctx cont...
    method _HttpRequestLogFilter_searchExpression (line 2438) | func (ec *executionContext) _HttpRequestLogFilter_searchExpression(ctx...
    method _HttpResponse_id (line 2470) | func (ec *executionContext) _HttpResponse_id(ctx context.Context, fiel...
    method _HttpResponse_proto (line 2505) | func (ec *executionContext) _HttpResponse_proto(ctx context.Context, f...
    method _HttpResponse_statusCode (line 2540) | func (ec *executionContext) _HttpResponse_statusCode(ctx context.Conte...
    method _HttpResponse_statusReason (line 2575) | func (ec *executionContext) _HttpResponse_statusReason(ctx context.Con...
    method _HttpResponse_body (line 2610) | func (ec *executionContext) _HttpResponse_body(ctx context.Context, fi...
    method _HttpResponse_headers (line 2642) | func (ec *executionContext) _HttpResponse_headers(ctx context.Context,...
    method _HttpResponseLog_id (line 2677) | func (ec *executionContext) _HttpResponseLog_id(ctx context.Context, f...
    method _HttpResponseLog_proto (line 2712) | func (ec *executionContext) _HttpResponseLog_proto(ctx context.Context...
    method _HttpResponseLog_statusCode (line 2747) | func (ec *executionContext) _HttpResponseLog_statusCode(ctx context.Co...
    method _HttpResponseLog_statusReason (line 2782) | func (ec *executionContext) _HttpResponseLog_statusReason(ctx context....
    method _HttpResponseLog_body (line 2817) | func (ec *executionContext) _HttpResponseLog_body(ctx context.Context,...
    method _HttpResponseLog_headers (line 2849) | func (ec *executionContext) _HttpResponseLog_headers(ctx context.Conte...
    method _InterceptSettings_requestsEnabled (line 2884) | func (ec *executionContext) _InterceptSettings_requestsEnabled(ctx con...
    method _InterceptSettings_responsesEnabled (line 2919) | func (ec *executionContext) _InterceptSettings_responsesEnabled(ctx co...
    method _InterceptSettings_requestFilter (line 2954) | func (ec *executionContext) _InterceptSettings_requestFilter(ctx conte...
    method _InterceptSettings_responseFilter (line 2986) | func (ec *executionContext) _InterceptSettings_responseFilter(ctx cont...
    method _ModifyRequestResult_success (line 3018) | func (ec *executionContext) _ModifyRequestResult_success(ctx context.C...
    method _ModifyResponseResult_success (line 3053) | func (ec *executionContext) _ModifyResponseResult_success(ctx context....
    method _Mutation_createProject (line 3088) | func (ec *executionContext) _Mutation_createProject(ctx context.Contex...
    method _Mutation_openProject (line 3127) | func (ec *executionContext) _Mutation_openProject(ctx context.Context,...
    method _Mutation_closeProject (line 3166) | func (ec *executionContext) _Mutation_closeProject(ctx context.Context...
    method _Mutation_deleteProject (line 3201) | func (ec *executionContext) _Mutation_deleteProject(ctx context.Contex...
    method _Mutation_clearHTTPRequestLog (line 3243) | func (ec *executionContext) _Mutation_clearHTTPRequestLog(ctx context....
    method _Mutation_setScope (line 3278) | func (ec *executionContext) _Mutation_setScope(ctx context.Context, fi...
    method _Mutation_setHttpRequestLogFilter (line 3320) | func (ec *executionContext) _Mutation_setHttpRequestLogFilter(ctx cont...
    method _Mutation_setSenderRequestFilter (line 3359) | func (ec *executionContext) _Mutation_setSenderRequestFilter(ctx conte...
    method _Mutation_createOrUpdateSenderRequest (line 3398) | func (ec *executionContext) _Mutation_createOrUpdateSenderRequest(ctx ...
    method _Mutation_createSenderRequestFromHttpRequestLog (line 3440) | func (ec *executionContext) _Mutation_createSenderRequestFromHttpReque...
    method _Mutation_sendRequest (line 3482) | func (ec *executionContext) _Mutation_sendRequest(ctx context.Context,...
    method _Mutation_deleteSenderRequests (line 3524) | func (ec *executionContext) _Mutation_deleteSenderRequests(ctx context...
    method _Mutation_modifyRequest (line 3559) | func (ec *executionContext) _Mutation_modifyRequest(ctx context.Contex...
    method _Mutation_cancelRequest (line 3601) | func (ec *executionContext) _Mutation_cancelRequest(ctx context.Contex...
    method _Mutation_modifyResponse (line 3643) | func (ec *executionContext) _Mutation_modifyResponse(ctx context.Conte...
    method _Mutation_cancelResponse (line 3685) | func (ec *executionContext) _Mutation_cancelResponse(ctx context.Conte...
    method _Mutation_updateInterceptSettings (line 3727) | func (ec *executionContext) _Mutation_updateInterceptSettings(ctx cont...
    method _Project_id (line 3769) | func (ec *executionContext) _Project_id(ctx context.Context, field gra...
    method _Project_name (line 3804) | func (ec *executionContext) _Project_name(ctx context.Context, field g...
    method _Project_isActive (line 3839) | func (ec *executionContext) _Project_isActive(ctx context.Context, fie...
    method _Project_settings (line 3874) | func (ec *executionContext) _Project_settings(ctx context.Context, fie...
    method _ProjectSettings_intercept (line 3909) | func (ec *executionContext) _ProjectSettings_intercept(ctx context.Con...
    method _Query_httpRequestLog (line 3944) | func (ec *executionContext) _Query_httpRequestLog(ctx context.Context,...
    method _Query_httpRequestLogs (line 3983) | func (ec *executionContext) _Query_httpRequestLogs(ctx context.Context...
    method _Query_httpRequestLogFilter (line 4018) | func (ec *executionContext) _Query_httpRequestLogFilter(ctx context.Co...
    method _Query_activeProject (line 4050) | func (ec *executionContext) _Query_activeProject(ctx context.Context, ...
    method _Query_projects (line 4082) | func (ec *executionContext) _Query_projects(ctx context.Context, field...
    method _Query_scope (line 4117) | func (ec *executionContext) _Query_scope(ctx context.Context, field gr...
    method _Query_senderRequest (line 4152) | func (ec *executionContext) _Query_senderRequest(ctx context.Context, ...
    method _Query_senderRequests (line 4191) | func (ec *executionContext) _Query_senderRequests(ctx context.Context,...
    method _Query_interceptedRequests (line 4226) | func (ec *executionContext) _Query_interceptedRequests(ctx context.Con...
    method _Query_interceptedRequest (line 4261) | func (ec *executionContext) _Query_interceptedRequest(ctx context.Cont...
    method _Query___type (line 4300) | func (ec *executionContext) _Query___type(ctx context.Context, field g...
    method _Query___schema (line 4339) | func (ec *executionContext) _Query___schema(ctx context.Context, field...
    method _ScopeHeader_key (line 4371) | func (ec *executionContext) _ScopeHeader_key(ctx context.Context, fiel...
    method _ScopeHeader_value (line 4403) | func (ec *executionContext) _ScopeHeader_value(ctx context.Context, fi...
    method _ScopeRule_url (line 4435) | func (ec *executionContext) _ScopeRule_url(ctx context.Context, field ...
    method _ScopeRule_header (line 4467) | func (ec *executionContext) _ScopeRule_header(ctx context.Context, fie...
    method _ScopeRule_body (line 4499) | func (ec *executionContext) _ScopeRule_body(ctx context.Context, field...
    method _SenderRequest_id (line 4531) | func (ec *executionContext) _SenderRequest_id(ctx context.Context, fie...
    method _SenderRequest_sourceRequestLogID (line 4566) | func (ec *executionContext) _SenderRequest_sourceRequestLogID(ctx cont...
    method _SenderRequest_url (line 4598) | func (ec *executionContext) _SenderRequest_url(ctx context.Context, fi...
    method _SenderRequest_method (line 4633) | func (ec *executionContext) _SenderRequest_method(ctx context.Context,...
    method _SenderRequest_proto (line 4668) | func (ec *executionContext) _SenderRequest_proto(ctx context.Context, ...
    method _SenderRequest_headers (line 4703) | func (ec *executionContext) _SenderRequest_headers(ctx context.Context...
    method _SenderRequest_body (line 4735) | func (ec *executionContext) _SenderRequest_body(ctx context.Context, f...
    method _SenderRequest_timestamp (line 4767) | func (ec *executionContext) _SenderRequest_timestamp(ctx context.Conte...
    method _SenderRequest_response (line 4802) | func (ec *executionContext) _SenderRequest_response(ctx context.Contex...
    method _SenderRequestFilter_onlyInScope (line 4834) | func (ec *executionContext) _SenderRequestFilter_onlyInScope(ctx conte...
    method _SenderRequestFilter_searchExpression (line 4869) | func (ec *executionContext) _SenderRequestFilter_searchExpression(ctx ...
    method ___Directive_name (line 4901) | func (ec *executionContext) ___Directive_name(ctx context.Context, fie...
    method ___Directive_description (line 4936) | func (ec *executionContext) ___Directive_description(ctx context.Conte...
    method ___Directive_locations (line 4968) | func (ec *executionContext) ___Directive_locations(ctx context.Context...
    method ___Directive_args (line 5003) | func (ec *executionContext) ___Directive_args(ctx context.Context, fie...
    method ___Directive_isRepeatable (line 5038) | func (ec *executionContext) ___Directive_isRepeatable(ctx context.Cont...
    method ___EnumValue_name (line 5073) | func (ec *executionContext) ___EnumValue_name(ctx context.Context, fie...
    method ___EnumValue_description (line 5108) | func (ec *executionContext) ___EnumValue_description(ctx context.Conte...
    method ___EnumValue_isDeprecated (line 5140) | func (ec *executionContext) ___EnumValue_isDeprecated(ctx context.Cont...
    method ___EnumValue_deprecationReason (line 5175) | func (ec *executionContext) ___EnumValue_deprecationReason(ctx context...
    method ___Field_name (line 5207) | func (ec *executionContext) ___Field_name(ctx context.Context, field g...
    method ___Field_description (line 5242) | func (ec *executionContext) ___Field_description(ctx context.Context, ...
    method ___Field_args (line 5274) | func (ec *executionContext) ___Field_args(ctx context.Context, field g...
    method ___Field_type (line 5309) | func (ec *executionContext) ___Field_type(ctx context.Context, field g...
    method ___Field_isDeprecated (line 5344) | func (ec *executionContext) ___Field_isDeprecated(ctx context.Context,...
    method ___Field_deprecationReason (line 5379) | func (ec *executionContext) ___Field_deprecationReason(ctx context.Con...
    method ___InputValue_name (line 5411) | func (ec *executionContext) ___InputValue_name(ctx context.Context, fi...
    method ___InputValue_description (line 5446) | func (ec *executionContext) ___InputValue_description(ctx context.Cont...
    method ___InputValue_type (line 5478) | func (ec *executionContext) ___InputValue_type(ctx context.Context, fi...
    method ___InputValue_defaultValue (line 5513) | func (ec *executionContext) ___InputValue_defaultValue(ctx context.Con...
    method ___Schema_types (line 5545) | func (ec *executionContext) ___Schema_types(ctx context.Context, field...
    method ___Schema_queryType (line 5580) | func (ec *executionContext) ___Schema_queryType(ctx context.Context, f...
    method ___Schema_mutationType (line 5615) | func (ec *executionContext) ___Schema_mutationType(ctx context.Context...
    method ___Schema_subscriptionType (line 5647) | func (ec *executionContext) ___Schema_subscriptionType(ctx context.Con...
    method ___Schema_directives (line 5679) | func (ec *executionContext) ___Schema_directives(ctx context.Context, ...
    method ___Type_kind (line 5714) | func (ec *executionContext) ___Type_kind(ctx context.Context, field gr...
    method ___Type_name (line 5749) | func (ec *executionContext) ___Type_name(ctx context.Context, field gr...
    method ___Type_description (line 5781) | func (ec *executionContext) ___Type_description(ctx context.Context, f...
    method ___Type_fields (line 5813) | func (ec *executionContext) ___Type_fields(ctx context.Context, field ...
    method ___Type_interfaces (line 5852) | func (ec *executionContext) ___Type_interfaces(ctx context.Context, fi...
    method ___Type_possibleTypes (line 5884) | func (ec *executionContext) ___Type_possibleTypes(ctx context.Context,...
    method ___Type_enumValues (line 5916) | func (ec *executionContext) ___Type_enumValues(ctx context.Context, fi...
    method ___Type_inputFields (line 5955) | func (ec *executionContext) ___Type_inputFields(ctx context.Context, f...
    method ___Type_ofType (line 5987) | func (ec *executionContext) ___Type_ofType(ctx context.Context, field ...
    method unmarshalInputHttpHeaderInput (line 6023) | func (ec *executionContext) unmarshalInputHttpHeaderInput(ctx context....
    method unmarshalInputHttpRequestLogFilterInput (line 6054) | func (ec *executionContext) unmarshalInputHttpRequestLogFilterInput(ct...
    method unmarshalInputModifyRequestInput (line 6085) | func (ec *executionContext) unmarshalInputModifyRequestInput(ctx conte...
    method unmarshalInputModifyResponseInput (line 6156) | func (ec *executionContext) unmarshalInputModifyResponseInput(ctx cont...
    method unmarshalInputScopeHeaderInput (line 6219) | func (ec *executionContext) unmarshalInputScopeHeaderInput(ctx context...
    method unmarshalInputScopeRuleInput (line 6250) | func (ec *executionContext) unmarshalInputScopeRuleInput(ctx context.C...
    method unmarshalInputSenderRequestFilterInput (line 6289) | func (ec *executionContext) unmarshalInputSenderRequestFilterInput(ctx...
    method unmarshalInputSenderRequestInput (line 6320) | func (ec *executionContext) unmarshalInputSenderRequestInput(ctx conte...
    method unmarshalInputUpdateInterceptSettingsInput (line 6383) | func (ec *executionContext) unmarshalInputUpdateInterceptSettingsInput...
    method _CancelRequestResult (line 6440) | func (ec *executionContext) _CancelRequestResult(ctx context.Context, ...
    method _CancelResponseResult (line 6467) | func (ec *executionContext) _CancelResponseResult(ctx context.Context,...
    method _ClearHTTPRequestLogResult (line 6494) | func (ec *executionContext) _ClearHTTPRequestLogResult(ctx context.Con...
    method _CloseProjectResult (line 6521) | func (ec *executionContext) _CloseProjectResult(ctx context.Context, s...
    method _DeleteProjectResult (line 6548) | func (ec *executionContext) _DeleteProjectResult(ctx context.Context, ...
    method _DeleteSenderRequestsResult (line 6575) | func (ec *executionContext) _DeleteSenderRequestsResult(ctx context.Co...
    method _HttpHeader (line 6602) | func (ec *executionContext) _HttpHeader(ctx context.Context, sel ast.S...
    method _HttpRequest (line 6634) | func (ec *executionContext) _HttpRequest(ctx context.Context, sel ast....
    method _HttpRequestLog (line 6685) | func (ec *executionContext) _HttpRequestLog(ctx context.Context, sel a...
    method _HttpRequestLogFilter (line 6741) | func (ec *executionContext) _HttpRequestLogFilter(ctx context.Context,...
    method _HttpResponse (line 6770) | func (ec *executionContext) _HttpResponse(ctx context.Context, sel ast...
    method _HttpResponseLog (line 6819) | func (ec *executionContext) _HttpResponseLog(ctx context.Context, sel ...
    method _InterceptSettings (line 6868) | func (ec *executionContext) _InterceptSettings(ctx context.Context, se...
    method _ModifyRequestResult (line 6904) | func (ec *executionContext) _ModifyRequestResult(ctx context.Context, ...
    method _ModifyResponseResult (line 6931) | func (ec *executionContext) _ModifyResponseResult(ctx context.Context,...
    method _Mutation (line 6958) | func (ec *executionContext) _Mutation(ctx context.Context, sel ast.Sel...
    method _Project (line 7057) | func (ec *executionContext) _Project(ctx context.Context, sel ast.Sele...
    method _ProjectSettings (line 7099) | func (ec *executionContext) _ProjectSettings(ctx context.Context, sel ...
    method _Query (line 7126) | func (ec *executionContext) _Query(ctx context.Context, sel ast.Select...
    method _ScopeHeader (line 7281) | func (ec *executionContext) _ScopeHeader(ctx context.Context, sel ast....
    method _ScopeRule (line 7307) | func (ec *executionContext) _ScopeRule(ctx context.Context, sel ast.Se...
    method _SenderRequest (line 7335) | func (ec *executionContext) _SenderRequest(ctx context.Context, sel as...
    method _SenderRequestFilter (line 7390) | func (ec *executionContext) _SenderRequestFilter(ctx context.Context, ...
    method ___Directive (line 7419) | func (ec *executionContext) ___Directive(ctx context.Context, sel ast....
    method ___EnumValue (line 7463) | func (ec *executionContext) ___EnumValue(ctx context.Context, sel ast....
    method ___Field (line 7499) | func (ec *executionContext) ___Field(ctx context.Context, sel ast.Sele...
    method ___InputValue (line 7545) | func (ec *executionContext) ___InputValue(ctx context.Context, sel ast...
    method ___Schema (line 7581) | func (ec *executionContext) ___Schema(ctx context.Context, sel ast.Sel...
    method ___Type (line 7622) | func (ec *executionContext) ___Type(ctx context.Context, sel ast.Selec...
    method unmarshalNBoolean2bool (line 7667) | func (ec *executionContext) unmarshalNBoolean2bool(ctx context.Context...
    method marshalNBoolean2bool (line 7672) | func (ec *executionContext) marshalNBoolean2bool(ctx context.Context, ...
    method marshalNCancelRequestResult2githubᚗcomᚋdstotijnᚋhettyᚋpkgᚋapiᚐCancelRequestResult (line 7682) | func (ec *executionContext) marshalNCancelRequestResult2githubᚗcomᚋdst...
    method marshalNCancelRequestResult2ᚖgithubᚗcomᚋdstotijnᚋhettyᚋpkgᚋapiᚐCancelRequestResult (line 7686) | func (ec *executionContext) marshalNCancelRequestResult2ᚖgithubᚗcomᚋds...
    method marshalNCancelResponseResult2githubᚗcomᚋdstotijnᚋhettyᚋpkgᚋapiᚐCancelResponseResult (line 7696) | func (ec *executionContext) marshalNCancelResponseResult2githubᚗcomᚋds...
    method marshalNCancelResponseResult2ᚖgithubᚗcomᚋdstotijnᚋhettyᚋpkgᚋapiᚐCancelResponseResult (line 7700) | func (ec *executionContext) marshalNCancelResponseResult2ᚖgithubᚗcomᚋd...
    method marshalNClearHTTPRequestLogResult2githubᚗcomᚋdstotijnᚋhettyᚋpkgᚋapiᚐClearHTTPRequestLogResult (line 7710) | func (ec *executionContext) marshalNClearHTTPRequestLogResult2githubᚗc...
    method marshalNClearHTTPRequestLogResult2ᚖgithubᚗcomᚋdstotijnᚋhettyᚋpkgᚋapiᚐClearHTTPRequestLogResult (line 7714) | func (ec *executionContext) marshalNClearHTTPRequestLogResult2ᚖgithubᚗ...
    method marshalNCloseProjectResult2githubᚗcomᚋdstotijnᚋhettyᚋpkgᚋapiᚐCloseProjectResult (line 7724) | func (ec *executionContext) marshalNCloseProjectResult2githubᚗcomᚋdsto...
    method marshalNCloseProjectResult2ᚖgithubᚗcomᚋdstotijnᚋhettyᚋpkgᚋapiᚐCloseProjectResult (line 7728) | func (ec *executionContext) marshalNCloseProjectResult2ᚖgithubᚗcomᚋdst...
    method marshalNDeleteProjectResult2githubᚗcomᚋdstotijnᚋhettyᚋpkgᚋapiᚐDeleteProjectResult (line 7738) | func (ec *executionContext) marshalNDeleteProjectResult2githubᚗcomᚋdst...
    method marshalNDeleteProjectResult2ᚖgithubᚗcomᚋdstotijnᚋhettyᚋpkgᚋapiᚐDeleteProjectResult (line 7742) | func (ec *executionContext) marshalNDeleteProjectResult2ᚖgithubᚗcomᚋds...
    method marshalNDeleteSenderRequestsResult2githubᚗcomᚋdstotijnᚋhettyᚋpkgᚋapiᚐDeleteSenderRequestsResult (line 7752) | func (ec *executionContext) marshalNDeleteSenderRequestsResult2githubᚗ...
    method marshalNDeleteSenderRequestsResult2ᚖgithubᚗcomᚋdstotijnᚋhettyᚋpkgᚋapiᚐDeleteSenderRequestsResult (line 7756) | func (ec *executionContext) marshalNDeleteSenderRequestsResult2ᚖgithub...
    method marshalNHttpHeader2githubᚗcomᚋdstotijnᚋhettyᚋpkgᚋapiᚐHTTPHeader (line 7766) | func (ec *executionContext) marshalNHttpHeader2githubᚗcomᚋdstotijnᚋhet...
    method marshalNHttpHeader2ᚕgithubᚗcomᚋdstotijnᚋhettyᚋpkgᚋapiᚐHTTPHeaderᚄ (line 7770) | func (ec *executionContext) marshalNHttpHeader2ᚕgithubᚗcomᚋdstotijnᚋhe...
    method unmarshalNHttpHeaderInput2githubᚗcomᚋdstotijnᚋhettyᚋpkgᚋapiᚐHTTPHeaderInput (line 7814) | func (ec *executionContext) unmarshalNHttpHeaderInput2githubᚗcomᚋdstot...
    method unmarshalNHttpMethod2githubᚗcomᚋdstotijnᚋhettyᚋpkgᚋapiᚐHTTPMethod (line 7819) | func (ec *executionContext) unmarshalNHttpMethod2githubᚗcomᚋdstotijnᚋh...
    method marshalNHttpMethod2githubᚗcomᚋdstotijnᚋhettyᚋpkgᚋapiᚐHTTPMethod (line 7825) | func (ec *executionContext) marshalNHttpMethod2githubᚗcomᚋdstotijnᚋhet...
    method unmarshalNHttpProtocol2githubᚗcomᚋdstotijnᚋhettyᚋpkgᚋapiᚐHTTPProtocol (line 7829) | func (ec *executionContext) unmarshalNHttpProtocol2githubᚗcomᚋdstotijn...
    method marshalNHttpProtocol2githubᚗcomᚋdstotijnᚋhettyᚋpkgᚋapiᚐHTTPProtocol (line 7835) | func (ec *executionContext) marshalNHttpProtocol2githubᚗcomᚋdstotijnᚋh...
    method marshalNHttpRequest2githubᚗcomᚋdstotijnᚋhettyᚋpkgᚋapiᚐHTTPRequest (line 7839) | func (ec *executionContext) marshalNHttpRequest2githubᚗcomᚋdstotijnᚋhe...
    method marshalNHttpRequest2ᚕgithubᚗcomᚋdstotijnᚋhettyᚋpkgᚋapiᚐHTTPRequestᚄ (line 7843) | func (ec *executionContext) marshalNHttpRequest2ᚕgithubᚗcomᚋdstotijnᚋh...
    method marshalNHttpRequestLog2githubᚗcomᚋdstotijnᚋhettyᚋpkgᚋapiᚐHTTPRequestLog (line 7887) | func (ec *executionContext) marshalNHttpRequestLog2githubᚗcomᚋdstotijn...
    method marshalNHttpRequestLog2ᚕgithubᚗcomᚋdstotijnᚋhettyᚋpkgᚋapiᚐHTTPRequestLogᚄ (line 7891) | func (ec *executionContext) marshalNHttpRequestLog2ᚕgithubᚗcomᚋdstotij...
    method unmarshalNID2githubᚗcomᚋoklogᚋulidᚐULID (line 7935) | func (ec *executionContext) unmarshalNID2githubᚗcomᚋoklogᚋulidᚐULID(ct...
    method marshalNID2githubᚗcomᚋoklogᚋulidᚐULID (line 7940) | func (ec *executionContext) marshalNID2githubᚗcomᚋoklogᚋulidᚐULID(ctx ...
    method unmarshalNInt2int (line 7950) | func (ec *executionContext) unmarshalNInt2int(ctx context.Context, v i...
    method marshalNInt2int (line 7955) | func (ec *executionContext) marshalNInt2int(ctx context.Context, sel a...
    method marshalNInterceptSettings2githubᚗcomᚋdstotijnᚋhettyᚋpkgᚋapiᚐInterceptSettings (line 7965) | func (ec *executionContext) marshalNInterceptSettings2githubᚗcomᚋdstot...
    method marshalNInterceptSettings2ᚖgithubᚗcomᚋdstotijnᚋhettyᚋpkgᚋapiᚐInterceptSettings (line 7969) | func (ec *executionContext) marshalNInterceptSettings2ᚖgithubᚗcomᚋdsto...
    method unmarshalNModifyRequestInput2githubᚗcomᚋdstotijnᚋhettyᚋpkgᚋapiᚐModifyRequestInput (line 7979) | func (ec *executionContext) unmarshalNModifyRequestInput2githubᚗcomᚋds...
    method marshalNModifyRequestResult2githubᚗcomᚋdstotijnᚋhettyᚋpkgᚋapiᚐModifyRequestResult (line 7984) | func (ec *executionContext) marshalNModifyRequestResult2githubᚗcomᚋdst...
    method marshalNModifyRequestResult2ᚖgithubᚗcomᚋdstotijnᚋhettyᚋpkgᚋapiᚐModifyRequestResult (line 7988) | func (ec *executionContext) marshalNModifyRequestResult2ᚖgithubᚗcomᚋds...
    method unmarshalNModifyResponseInput2githubᚗcomᚋdstotijnᚋhettyᚋpkgᚋapiᚐModifyResponseInput (line 7998) | func (ec *executionContext) unmarshalNModifyResponseInput2githubᚗcomᚋd...
    method marshalNModifyResponseResult2githubᚗcomᚋdstotijnᚋhettyᚋpkgᚋapiᚐModifyResponseResult (line 8003) | func (ec *executionContext) marshalNModifyResponseResult2githubᚗcomᚋds...
    method marshalNModifyResponseResult2ᚖgithubᚗcomᚋdstotijnᚋhettyᚋpkgᚋapiᚐModifyResponseResult (line 8007) | func (ec *executionContext) marshalNModifyResponseResult2ᚖgithubᚗcomᚋd...
    method marshalNProject2githubᚗcomᚋdstotijnᚋhettyᚋpkgᚋapiᚐProject (line 8017) | func (ec *executionContext) marshalNProject2githubᚗcomᚋdstotijnᚋhettyᚋ...
    method marshalNProject2ᚕgithubᚗcomᚋdstotijnᚋhettyᚋpkgᚋapiᚐProjectᚄ (line 8021) | func (ec *executionContext) marshalNProject2ᚕgithubᚗcomᚋdstotijnᚋhetty...
    method marshalNProjectSettings2ᚖgithubᚗcomᚋdstotijnᚋhettyᚋpkgᚋapiᚐProjectSettings (line 8065) | func (ec *executionContext) marshalNProjectSettings2ᚖgithubᚗcomᚋdstoti...
    method marshalNScopeRule2githubᚗcomᚋdstotijnᚋhettyᚋpkgᚋapiᚐScopeRule (line 8075) | func (ec *executionContext) marshalNScopeRule2githubᚗcomᚋdstotijnᚋhett...
    method marshalNScopeRule2ᚕgithubᚗcomᚋdstotijnᚋhettyᚋpkgᚋapiᚐScopeRuleᚄ (line 8079) | func (ec *executionContext) marshalNScopeRule2ᚕgithubᚗcomᚋdstotijnᚋhet...
    method unmarshalNScopeRuleInput2githubᚗcomᚋdstotijnᚋhettyᚋpkgᚋapiᚐScopeRuleInput (line 8123) | func (ec *executionContext) unmarshalNScopeRuleInput2githubᚗcomᚋdstoti...
    method unmarshalNScopeRuleInput2ᚕgithubᚗcomᚋdstotijnᚋhettyᚋpkgᚋapiᚐScopeRuleInputᚄ (line 8128) | func (ec *executionContext) unmarshalNScopeRuleInput2ᚕgithubᚗcomᚋdstot...
    method marshalNSenderRequest2githubᚗcomᚋdstotijnᚋhettyᚋpkgᚋapiᚐSenderRequest (line 8149) | func (ec *executionContext) marshalNSenderRequest2githubᚗcomᚋdstotijnᚋ...
    method marshalNSenderRequest2ᚕgithubᚗcomᚋdstotijnᚋhettyᚋpkgᚋapiᚐSenderRequestᚄ (line 8153) | func (ec *executionContext) marshalNSenderRequest2ᚕgithubᚗcomᚋdstotijn...
    method marshalNSenderRequest2ᚖgithubᚗcomᚋdstotijnᚋhettyᚋpkgᚋapiᚐSenderRequest (line 8197) | func (ec *executionContext) marshalNSenderRequest2ᚖgithubᚗcomᚋdstotijn...
    method unmarshalNSenderRequestInput2githubᚗcomᚋdstotijnᚋhettyᚋpkgᚋapiᚐSenderRequestInput (line 8207) | func (ec *executionContext) unmarshalNSenderRequestInput2githubᚗcomᚋds...
    method unmarshalNString2string (line 8212) | func (ec *executionContext) unmarshalNString2string(ctx context.Contex...
    method marshalNString2string (line 8217) | func (ec *executionContext) marshalNString2string(ctx context.Context,...
    method unmarshalNTime2timeᚐTime (line 8227) | func (ec *executionContext) unmarshalNTime2timeᚐTime(ctx context.Conte...
    method marshalNTime2timeᚐTime (line 8232) | func (ec *executionContext) marshalNTime2timeᚐTime(ctx context.Context...
    method unmarshalNURL2ᚖnetᚋurlᚐURL (line 8242) | func (ec *executionContext) unmarshalNURL2ᚖnetᚋurlᚐURL(ctx context.Con...
    method marshalNURL2ᚖnetᚋurlᚐURL (line 8247) | func (ec *executionContext) marshalNURL2ᚖnetᚋurlᚐURL(ctx context.Conte...
    method unmarshalNUpdateInterceptSettingsInput2githubᚗcomᚋdstotijnᚋhettyᚋpkgᚋapiᚐUpdateInterceptSettingsInput (line 8263) | func (ec *executionContext) unmarshalNUpdateInterceptSettingsInput2git...
    method marshalN__Directive2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐDirective (line 8268) | func (ec *executionContext) marshalN__Directive2githubᚗcomᚋ99designsᚋg...
    method marshalN__Directive2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐDirectiveᚄ (line 8272) | func (ec *executionContext) marshalN__Directive2ᚕgithubᚗcomᚋ99designsᚋ...
    method unmarshalN__DirectiveLocation2string (line 8316) | func (ec *executionContext) unmarshalN__DirectiveLocation2string(ctx c...
    method marshalN__DirectiveLocation2string (line 8321) | func (ec *executionContext) marshalN__DirectiveLocation2string(ctx con...
    method unmarshalN__DirectiveLocation2ᚕstringᚄ (line 8331) | func (ec *executionContext) unmarshalN__DirectiveLocation2ᚕstringᚄ(ctx...
    method marshalN__DirectiveLocation2ᚕstringᚄ (line 8352) | func (ec *executionContext) marshalN__DirectiveLocation2ᚕstringᚄ(ctx c...
    method marshalN__EnumValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValue (line 8396) | func (ec *executionContext) marshalN__EnumValue2githubᚗcomᚋ99designsᚋg...
    method marshalN__Field2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐField (line 8400) | func (ec *executionContext) marshalN__Field2githubᚗcomᚋ99designsᚋgqlge...
    method marshalN__InputValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValue (line 8404) | func (ec *executionContext) marshalN__InputValue2githubᚗcomᚋ99designsᚋ...
    method marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ (line 8408) | func (ec *executionContext) marshalN__InputValue2ᚕgithubᚗcomᚋ99designs...
    method marshalN__Type2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType (line 8452) | func (ec *executionContext) marshalN__Type2githubᚗcomᚋ99designsᚋgqlgen...
    method marshalN__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ (line 8456) | func (ec *executionContext) marshalN__Type2ᚕgithubᚗcomᚋ99designsᚋgqlge...
    method marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType (line 8500) | func (ec *executionContext) marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlge...
    method unmarshalN__TypeKind2string (line 8510) | func (ec *executionContext) unmarshalN__TypeKind2string(ctx context.Co...
    method marshalN__TypeKind2string (line 8515) | func (ec *executionContext) marshalN__TypeKind2string(ctx context.Cont...
    method unmarshalOBoolean2bool (line 8525) | func (ec *executionContext) unmarshalOBoolean2bool(ctx context.Context...
    method marshalOBoolean2bool (line 8530) | func (ec *executionContext) marshalOBoolean2bool(ctx context.Context, ...
    method unmarshalOBoolean2ᚖbool (line 8534) | func (ec *executionContext) unmarshalOBoolean2ᚖbool(ctx context.Contex...
    method marshalOBoolean2ᚖbool (line 8542) | func (ec *executionContext) marshalOBoolean2ᚖbool(ctx context.Context,...
    method marshalOHttpHeader2ᚕgithubᚗcomᚋdstotijnᚋhettyᚋpkgᚋapiᚐHTTPHeaderᚄ (line 8549) | func (ec *executionContext) marshalOHttpHeader2ᚕgithubᚗcomᚋdstotijnᚋhe...
    method unmarshalOHttpHeaderInput2ᚕgithubᚗcomᚋdstotijnᚋhettyᚋpkgᚋapiᚐHTTPHeaderInputᚄ (line 8596) | func (ec *executionContext) unmarshalOHttpHeaderInput2ᚕgithubᚗcomᚋdsto...
    method unmarshalOHttpMethod2ᚖgithubᚗcomᚋdstotijnᚋhettyᚋpkgᚋapiᚐHTTPMethod (line 8620) | func (ec *executionContext) unmarshalOHttpMethod2ᚖgithubᚗcomᚋdstotijnᚋ...
    method marshalOHttpMethod2ᚖgithubᚗcomᚋdstotijnᚋhettyᚋpkgᚋapiᚐHTTPMethod (line 8629) | func (ec *executionContext) marshalOHttpMethod2ᚖgithubᚗcomᚋdstotijnᚋhe...
    method unmarshalOHttpProtocol2ᚖgithubᚗcomᚋdstotijnᚋhettyᚋpkgᚋapiᚐHTTPProtocol (line 8636) | func (ec *executionContext) unmarshalOHttpProtocol2ᚖgithubᚗcomᚋdstotij...
    method marshalOHttpProtocol2ᚖgithubᚗcomᚋdstotijnᚋhettyᚋpkgᚋapiᚐHTTPProtocol (line 8645) | func (ec *executionContext) marshalOHttpProtocol2ᚖgithubᚗcomᚋdstotijnᚋ...
    method marshalOHttpRequest2ᚖgithubᚗcomᚋdstotijnᚋhettyᚋpkgᚋapiᚐHTTPRequest (line 8652) | func (ec *executionContext) marshalOHttpRequest2ᚖgithubᚗcomᚋdstotijnᚋh...
    method marshalOHttpRequestLog2ᚖgithubᚗcomᚋdstotijnᚋhettyᚋpkgᚋapiᚐHTTPRequestLog (line 8659) | func (ec *executionContext) marshalOHttpRequestLog2ᚖgithubᚗcomᚋdstotij...
    method marshalOHttpRequestLogFilter2ᚖgithubᚗcomᚋdstotijnᚋhettyᚋpkgᚋapiᚐHTTPRequestLogFilter (line 8666) | func (ec *executionContext) marshalOHttpRequestLogFilter2ᚖgithubᚗcomᚋd...
    method unmarshalOHttpRequestLogFilterInput2ᚖgithubᚗcomᚋdstotijnᚋhettyᚋpkgᚋapiᚐHTTPRequestLogFilterInput (line 8673) | func (ec *executionContext) unmarshalOHttpRequestLogFilterInput2ᚖgithu...
    method marshalOHttpResponse2ᚖgithubᚗcomᚋdstotijnᚋhettyᚋpkgᚋapiᚐHTTPResponse (line 8681) | func (ec *executionContext) marshalOHttpResponse2ᚖgithubᚗcomᚋdstotijnᚋ...
    method marshalOHttpResponseLog2ᚖgithubᚗcomᚋdstotijnᚋhettyᚋpkgᚋapiᚐHTTPResponseLog (line 8688) | func (ec *executionContext) marshalOHttpResponseLog2ᚖgithubᚗcomᚋdstoti...
    method unmarshalOID2ᚖgithubᚗcomᚋoklogᚋulidᚐULID (line 8695) | func (ec *executionContext) unmarshalOID2ᚖgithubᚗcomᚋoklogᚋulidᚐULID(c...
    method marshalOID2ᚖgithubᚗcomᚋoklogᚋulidᚐULID (line 8703) | func (ec *executionContext) marshalOID2ᚖgithubᚗcomᚋoklogᚋulidᚐULID(ctx...
    method marshalOProject2ᚖgithubᚗcomᚋdstotijnᚋhettyᚋpkgᚋapiᚐProject (line 8710) | func (ec *executionContext) marshalOProject2ᚖgithubᚗcomᚋdstotijnᚋhetty...
    method unmarshalORegexp2ᚖstring (line 8717) | func (ec *executionContext) unmarshalORegexp2ᚖstring(ctx context.Conte...
    method marshalORegexp2ᚖstring (line 8725) | func (ec *executionContext) marshalORegexp2ᚖstring(ctx context.Context...
    method marshalOScopeHeader2ᚖgithubᚗcomᚋdstotijnᚋhettyᚋpkgᚋapiᚐScopeHeader (line 8732) | func (ec *executionContext) marshalOScopeHeader2ᚖgithubᚗcomᚋdstotijnᚋh...
    method unmarshalOScopeHeaderInput2ᚖgithubᚗcomᚋdstotijnᚋhettyᚋpkgᚋapiᚐScopeHeaderInput (line 8739) | func (ec *executionContext) unmarshalOScopeHeaderInput2ᚖgithubᚗcomᚋdst...
    method marshalOSenderRequest2ᚖgithubᚗcomᚋdstotijnᚋhettyᚋpkgᚋapiᚐSenderRequest (line 8747) | func (ec *executionContext) marshalOSenderRequest2ᚖgithubᚗcomᚋdstotijn...
    method marshalOSenderRequestFilter2ᚖgithubᚗcomᚋdstotijnᚋhettyᚋpkgᚋapiᚐSenderRequestFilter (line 8754) | func (ec *executionContext) marshalOSenderRequestFilter2ᚖgithubᚗcomᚋds...
    method unmarshalOSenderRequestFilterInput2ᚖgithubᚗcomᚋdstotijnᚋhettyᚋpkgᚋapiᚐSenderRequestFilterInput (line 8761) | func (ec *executionContext) unmarshalOSenderRequestFilterInput2ᚖgithub...
    method unmarshalOString2string (line 8769) | func (ec *executionContext) unmarshalOString2string(ctx context.Contex...
    method marshalOString2string (line 8774) | func (ec *executionContext) marshalOString2string(ctx context.Context,...
    method unmarshalOString2ᚖstring (line 8778) | func (ec *executionContext) unmarshalOString2ᚖstring(ctx context.Conte...
    method marshalOString2ᚖstring (line 8786) | func (ec *executionContext) marshalOString2ᚖstring(ctx context.Context...
    method marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValueᚄ (line 8793) | func (ec *executionContext) marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋ...
    method marshalO__Field2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐFieldᚄ (line 8840) | func (ec *executionContext) marshalO__Field2ᚕgithubᚗcomᚋ99designsᚋgqlg...
    method marshalO__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ (line 8887) | func (ec *executionContext) marshalO__InputValue2ᚕgithubᚗcomᚋ99designs...
    method marshalO__Schema2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐSchema (line 8934) | func (ec *executionContext) marshalO__Schema2ᚖgithubᚗcomᚋ99designsᚋgql...
    method marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ (line 8941) | func (ec *executionContext) marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlge...
    method marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType (line 8988) | func (ec *executionContext) marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlge...

FILE: pkg/api/http.go
  function HTTPHandler (line 11) | func HTTPHandler(resolver *Resolver, gqlEndpoint string) http.Handler {

FILE: pkg/api/models.go
  function MarshalULID (line 13) | func MarshalULID(u ulid.ULID) graphql.Marshaler {
  function UnmarshalULID (line 19) | func UnmarshalULID(v interface{}) (ulid.ULID, error) {
  function MarshalURL (line 33) | func MarshalURL(u *url.URL) graphql.Marshaler {
  function UnmarshalURL (line 39) | func UnmarshalURL(v interface{}) (*url.URL, error) {
  type HTTPHeaders (line 53) | type HTTPHeaders
    method Len (line 55) | func (h HTTPHeaders) Len() int {
    method Less (line 59) | func (h HTTPHeaders) Less(i, j int) bool {
    method Swap (line 63) | func (h HTTPHeaders) Swap(i, j int) {

FILE: pkg/api/models_gen.go
  type CancelRequestResult (line 15) | type CancelRequestResult struct
  type CancelResponseResult (line 19) | type CancelResponseResult struct
  type ClearHTTPRequestLogResult (line 23) | type ClearHTTPRequestLogResult struct
  type CloseProjectResult (line 27) | type CloseProjectResult struct
  type DeleteProjectResult (line 31) | type DeleteProjectResult struct
  type DeleteSenderRequestsResult (line 35) | type DeleteSenderRequestsResult struct
  type HTTPHeader (line 39) | type HTTPHeader struct
  type HTTPHeaderInput (line 44) | type HTTPHeaderInput struct
  type HTTPRequest (line 49) | type HTTPRequest struct
  type HTTPRequestLog (line 59) | type HTTPRequestLog struct
  type HTTPRequestLogFilter (line 70) | type HTTPRequestLogFilter struct
  type HTTPRequestLogFilterInput (line 75) | type HTTPRequestLogFilterInput struct
  type HTTPResponse (line 80) | type HTTPResponse struct
  type HTTPResponseLog (line 90) | type HTTPResponseLog struct
  type InterceptSettings (line 100) | type InterceptSettings struct
  type ModifyRequestInput (line 107) | type ModifyRequestInput struct
  type ModifyRequestResult (line 117) | type ModifyRequestResult struct
  type ModifyResponseInput (line 121) | type ModifyResponseInput struct
  type ModifyResponseResult (line 130) | type ModifyResponseResult struct
  type Project (line 134) | type Project struct
  type ProjectSettings (line 141) | type ProjectSettings struct
  type ScopeHeader (line 145) | type ScopeHeader struct
  type ScopeHeaderInput (line 150) | type ScopeHeaderInput struct
  type ScopeRule (line 155) | type ScopeRule struct
  type ScopeRuleInput (line 161) | type ScopeRuleInput struct
  type SenderRequest (line 167) | type SenderRequest struct
  type SenderRequestFilter (line 179) | type SenderRequestFilter struct
  type SenderRequestFilterInput (line 184) | type SenderRequestFilterInput struct
  type SenderRequestInput (line 189) | type SenderRequestInput struct
  type UpdateInterceptSettingsInput (line 198) | type UpdateInterceptSettingsInput struct
  type HTTPMethod (line 205) | type HTTPMethod
    method IsValid (line 231) | func (e HTTPMethod) IsValid() bool {
    method String (line 239) | func (e HTTPMethod) String() string {
    method UnmarshalGQL (line 243) | func (e *HTTPMethod) UnmarshalGQL(v interface{}) error {
    method MarshalGQL (line 256) | func (e HTTPMethod) MarshalGQL(w io.Writer) {
  constant HTTPMethodGet (line 208) | HTTPMethodGet     HTTPMethod = "GET"
  constant HTTPMethodHead (line 209) | HTTPMethodHead    HTTPMethod = "HEAD"
  constant HTTPMethodPost (line 210) | HTTPMethodPost    HTTPMethod = "POST"
  constant HTTPMethodPut (line 211) | HTTPMethodPut     HTTPMethod = "PUT"
  constant HTTPMethodDelete (line 212) | HTTPMethodDelete  HTTPMethod = "DELETE"
  constant HTTPMethodConnect (line 213) | HTTPMethodConnect HTTPMethod = "CONNECT"
  constant HTTPMethodOptions (line 214) | HTTPMethodOptions HTTPMethod = "OPTIONS"
  constant HTTPMethodTrace (line 215) | HTTPMethodTrace   HTTPMethod = "TRACE"
  constant HTTPMethodPatch (line 216) | HTTPMethodPatch   HTTPMethod = "PATCH"
  type HTTPProtocol (line 260) | type HTTPProtocol
    method IsValid (line 274) | func (e HTTPProtocol) IsValid() bool {
    method String (line 282) | func (e HTTPProtocol) String() string {
    method UnmarshalGQL (line 286) | func (e *HTTPProtocol) UnmarshalGQL(v interface{}) error {
    method MarshalGQL (line 299) | func (e HTTPProtocol) MarshalGQL(w io.Writer) {
  constant HTTPProtocolHTTP10 (line 263) | HTTPProtocolHTTP10 HTTPProtocol = "HTTP10"
  constant HTTPProtocolHTTP11 (line 264) | HTTPProtocolHTTP11 HTTPProtocol = "HTTP11"
  constant HTTPProtocolHTTP20 (line 265) | HTTPProtocolHTTP20 HTTPProtocol = "HTTP20"

FILE: pkg/api/resolvers.go
  type Resolver (line 42) | type Resolver struct
    method Query (line 54) | func (r *Resolver) Query() QueryResolver       { return &queryResolver...
    method Mutation (line 55) | func (r *Resolver) Mutation() MutationResolver { return &mutationResol...
  type queryResolver (line 50) | type queryResolver struct
    method HTTPRequestLogs (line 57) | func (r *queryResolver) HTTPRequestLogs(ctx context.Context) ([]HTTPRe...
    method HTTPRequestLog (line 79) | func (r *queryResolver) HTTPRequestLog(ctx context.Context, id ulid.UL...
    method ActiveProject (line 211) | func (r *queryResolver) ActiveProject(ctx context.Context) (*Project, ...
    method Projects (line 224) | func (r *queryResolver) Projects(ctx context.Context) ([]Project, erro...
    method Scope (line 238) | func (r *queryResolver) Scope(ctx context.Context) ([]ScopeRule, error) {
    method HTTPRequestLogFilter (line 332) | func (r *queryResolver) HTTPRequestLogFilter(ctx context.Context) (*HT...
    method SenderRequest (line 355) | func (r *queryResolver) SenderRequest(ctx context.Context, id ulid.ULI...
    method SenderRequests (line 371) | func (r *queryResolver) SenderRequests(ctx context.Context) ([]SenderR...
    method InterceptedRequests (line 524) | func (r *queryResolver) InterceptedRequests(ctx context.Context) (http...
    method InterceptedRequest (line 539) | func (r *queryResolver) InterceptedRequest(ctx context.Context, id uli...
  type mutationResolver (line 51) | type mutationResolver struct
    method CreateProject (line 185) | func (r *mutationResolver) CreateProject(ctx context.Context, name str...
    method OpenProject (line 198) | func (r *mutationResolver) OpenProject(ctx context.Context, id ulid.UL...
    method CloseProject (line 253) | func (r *mutationResolver) CloseProject(ctx context.Context) (*ClosePr...
    method DeleteProject (line 261) | func (r *mutationResolver) DeleteProject(ctx context.Context, id ulid....
    method ClearHTTPRequestLog (line 271) | func (r *mutationResolver) ClearHTTPRequestLog(ctx context.Context) (*...
    method SetScope (line 286) | func (r *mutationResolver) SetScope(ctx context.Context, input []Scope...
    method SetHTTPRequestLogFilter (line 336) | func (r *mutationResolver) SetHTTPRequestLogFilter(
    method SetSenderRequestFilter (line 393) | func (r *mutationResolver) SetSenderRequestFilter(
    method CreateOrUpdateSenderRequest (line 412) | func (r *mutationResolver) CreateOrUpdateSenderRequest(
    method CreateSenderRequestFromHTTPRequestLog (line 456) | func (r *mutationResolver) CreateSenderRequestFromHTTPRequestLog(
    method SendRequest (line 475) | func (r *mutationResolver) SendRequest(ctx context.Context, id ulid.UL...
    method DeleteSenderRequests (line 509) | func (r *mutationResolver) DeleteSenderRequests(ctx context.Context) (...
    method ModifyRequest (line 555) | func (r *mutationResolver) ModifyRequest(ctx context.Context, input Mo...
    method CancelRequest (line 579) | func (r *mutationResolver) CancelRequest(ctx context.Context, id ulid....
    method ModifyResponse (line 588) | func (r *mutationResolver) ModifyResponse(
    method CancelResponse (line 623) | func (r *mutationResolver) CancelResponse(ctx context.Context, request...
    method UpdateInterceptSettings (line 632) | func (r *mutationResolver) UpdateInterceptSettings(
  function parseRequestLog (line 95) | func parseRequestLog(reqLog reqlog.RequestLog) (HTTPRequestLog, error) {
  function parseResponseLog (line 146) | func parseResponseLog(resLog reqlog.ResponseLog) (HTTPResponseLog, error) {
  function regexpToStringPtr (line 243) | func regexpToStringPtr(r *regexp.Regexp) *string {
  function parseSenderRequest (line 684) | func parseSenderRequest(req sender.Request) (SenderRequest, error) {
  function parseHTTPRequest (line 741) | func parseHTTPRequest(req *http.Request) (HTTPRequest, error) {
  function parseHTTPResponse (line 793) | func parseHTTPResponse(res *http.Response) (HTTPResponse, error) {
  function parseInterceptItem (line 845) | func parseInterceptItem(item intercept.Item) (req HTTPRequest, err error) {
  function parseProject (line 868) | func parseProject(projSvc *proj.Service, p proj.Project) Project {
  function stringPtrToRegexp (line 894) | func stringPtrToRegexp(s *string) (*regexp.Regexp, error) {
  function scopeToScopeRules (line 902) | func scopeToScopeRules(rules []scope.Rule) []ScopeRule {
  function findRequestsFilterFromInput (line 919) | func findRequestsFilterFromInput(input *HTTPRequestLogFilterInput) (find...
  function findSenderRequestsFilterFromInput (line 940) | func findSenderRequestsFilterFromInput(input *SenderRequestFilterInput) ...
  function findReqFilterToHTTPReqLogFilter (line 961) | func findReqFilterToHTTPReqLogFilter(findReqFilter reqlog.FindRequestsFi...
  function findReqFilterToSenderReqFilter (line 979) | func findReqFilterToSenderReqFilter(findReqFilter sender.FindRequestsFil...
  function noActiveProjectErr (line 997) | func noActiveProjectErr(ctx context.Context) error {

FILE: pkg/chrome/chrome.go
  type Config (line 17) | type Config struct
  function NewExecAllocator (line 25) | func NewExecAllocator(ctx context.Context, cfg Config) (context.Context,...

FILE: pkg/db/bolt/bolt.go
  type Database (line 10) | type Database struct
    method Close (line 25) | func (db *Database) Close() error {
  function OpenDatabase (line 15) | func OpenDatabase(path string, opts *bolt.Options) (*Database, error) {
  function DatabaseFromBoltDB (line 31) | func DatabaseFromBoltDB(db *bolt.DB) (*Database, error) {
  function createNestedBucket (line 47) | func createNestedBucket(tx *bolt.Tx, names ...[]byte) (b *bolt.Bucket, e...

FILE: pkg/db/bolt/logger.go
  type Logger (line 11) | type Logger struct
    method Warning (line 16) | func (l *Logger) Warning(v ...interface{}) {
    method Warningf (line 21) | func (l *Logger) Warningf(format string, v ...interface{}) {

FILE: pkg/db/bolt/proj.go
  function projectsBucket (line 26) | func projectsBucket(tx *bolt.Tx) (*bolt.Bucket, error) {
  function projectBucket (line 35) | func projectBucket(tx *bolt.Tx, projectID []byte) (*bolt.Bucket, error) {
  method UpsertProject (line 49) | func (db *Database) UpsertProject(ctx context.Context, project proj.Proj...
  method FindProjectByID (line 87) | func (db *Database) FindProjectByID(ctx context.Context, projectID ulid....
  method DeleteProject (line 116) | func (db *Database) DeleteProject(ctx context.Context, projectID ulid.UL...
  method Projects (line 137) | func (db *Database) Projects(ctx context.Context) ([]proj.Project, error) {

FILE: pkg/db/bolt/proj_test.go
  function TestUpsertProject (line 38) | func TestUpsertProject(t *testing.T) {
  function TestFindProjectByID (line 108) | func TestFindProjectByID(t *testing.T) {
  function TestDeleteProject (line 182) | func TestDeleteProject(t *testing.T) {
  function TestProjects (line 221) | func TestProjects(t *testing.T) {

FILE: pkg/db/bolt/reqlog.go
  function requestLogsBucket (line 21) | func requestLogsBucket(tx *bolt.Tx, projectID ulid.ULID) (*bolt.Bucket, ...
  method FindRequestLogs (line 35) | func (db *Database) FindRequestLogs(ctx context.Context, filter reqlog.F...
  method FindRequestLogByID (line 90) | func (db *Database) FindRequestLogByID(ctx context.Context, projectID, r...
  method StoreRequestLog (line 115) | func (db *Database) StoreRequestLog(ctx context.Context, reqLog reqlog.R...
  method StoreResponseLog (line 143) | func (db *Database) StoreResponseLog(ctx context.Context, projectID, req...
  method ClearRequestLogs (line 190) | func (db *Database) ClearRequestLogs(ctx context.Context, projectID ulid...

FILE: pkg/db/bolt/reqlog_test.go
  function TestFindRequestLogs (line 20) | func TestFindRequestLogs(t *testing.T) {
  function mustParseURL (line 132) | func mustParseURL(t *testing.T, s string) *url.URL {

FILE: pkg/db/bolt/sender.go
  function senderReqsBucket (line 21) | func senderReqsBucket(tx *bolt.Tx, projectID ulid.ULID) (*bolt.Bucket, e...
  method StoreSenderRequest (line 35) | func (db *Database) StoreSenderRequest(ctx context.Context, req sender.R...
  method FindSenderRequestByID (line 63) | func (db *Database) FindSenderRequestByID(ctx context.Context, projectID...
  method FindSenderRequests (line 93) | func (db *Database) FindSenderRequests(ctx context.Context, filter sende...
  method DeleteSenderRequests (line 153) | func (db *Database) DeleteSenderRequests(ctx context.Context, projectID ...

FILE: pkg/db/bolt/sender_test.go
  function TestFindRequestByID (line 30) | func TestFindRequestByID(t *testing.T) {
  function TestFindSenderRequests (line 110) | func TestFindSenderRequests(t *testing.T) {

FILE: pkg/filter/ast.go
  type Expression (line 10) | type Expression interface
  type PrefixExpression (line 14) | type PrefixExpression struct
    method String (line 19) | func (pe PrefixExpression) String() string {
  type InfixExpression (line 30) | type InfixExpression struct
    method String (line 36) | func (ie InfixExpression) String() string {
  type StringLiteral (line 49) | type StringLiteral struct
    method String (line 53) | func (sl StringLiteral) String() string {
  type RegexpLiteral (line 57) | type RegexpLiteral struct
    method String (line 61) | func (rl RegexpLiteral) String() string {
    method MarshalBinary (line 65) | func (rl RegexpLiteral) MarshalBinary() ([]byte, error) {
    method UnmarshalBinary (line 69) | func (rl *RegexpLiteral) UnmarshalBinary(data []byte) error {
  function init (line 80) | func init() {

FILE: pkg/filter/ast_test.go
  function TestExpressionString (line 10) | func TestExpressionString(t *testing.T) {

FILE: pkg/filter/http.go
  function MatchHTTPHeaders (line 9) | func MatchHTTPHeaders(op TokenType, expr Expression, headers http.Header...

FILE: pkg/filter/lexer.go
  type TokenType (line 9) | type TokenType
    method String (line 97) | func (tt TokenType) String() string {
  type Token (line 11) | type Token struct
  constant eof (line 16) | eof = 0
  constant TokInvalid (line 21) | TokInvalid TokenType = iota
  constant TokEOF (line 22) | TokEOF
  constant TokParenOpen (line 23) | TokParenOpen
  constant TokParenClose (line 24) | TokParenClose
  constant TokString (line 27) | TokString
  constant TokOpNot (line 30) | TokOpNot
  constant TokOpAnd (line 31) | TokOpAnd
  constant TokOpOr (line 32) | TokOpOr
  constant TokOpEq (line 35) | TokOpEq
  constant TokOpNotEq (line 36) | TokOpNotEq
  constant TokOpGt (line 37) | TokOpGt
  constant TokOpLt (line 38) | TokOpLt
  constant TokOpGtEq (line 39) | TokOpGtEq
  constant TokOpLtEq (line 40) | TokOpLtEq
  constant TokOpRe (line 41) | TokOpRe
  constant TokOpNotRe (line 42) | TokOpNotRe
  type stateFn (line 72) | type stateFn
  type Lexer (line 74) | type Lexer struct
    method Next (line 93) | func (l *Lexer) Next() Token {
    method run (line 105) | func (l *Lexer) run(init stateFn) {
    method read (line 112) | func (l *Lexer) read() (r rune) {
    method emit (line 124) | func (l *Lexer) emit(tokenType TokenType) {
    method ignore (line 133) | func (l *Lexer) ignore() {
    method skip (line 137) | func (l *Lexer) skip() {
    method backup (line 142) | func (l *Lexer) backup() {
    method errorf (line 146) | func (l *Lexer) errorf(format string, args ...interface{}) stateFn {
    method delimString (line 217) | func (l *Lexer) delimString(delim rune) stateFn {
    method emitUnquotedString (line 258) | func (l *Lexer) emitUnquotedString() {
  function NewLexer (line 82) | func NewLexer(input string) *Lexer {
  function begin (line 155) | func begin(l *Lexer) stateFn {
  function unquotedString (line 235) | func unquotedString(l *Lexer) stateFn {
  function isReserved (line 268) | func isReserved(r rune) bool {

FILE: pkg/filter/lexer_test.go
  function TestNextToken (line 5) | func TestNextToken(t *testing.T) {

FILE: pkg/filter/parser.go
  type precedence (line 8) | type precedence
  constant _ (line 11) | _ precedence = iota
  constant precLowest (line 12) | precLowest
  constant precAnd (line 13) | precAnd
  constant precOr (line 14) | precOr
  constant precNot (line 15) | precNot
  constant precEq (line 16) | precEq
  constant precLessGreater (line 17) | precLessGreater
  constant precPrefix (line 18) | precPrefix
  constant precGroup (line 19) | precGroup
  type prefixParser (line 23) | type prefixParser
  type infixParser (line 24) | type infixParser
  function init (line 47) | func init() {
  type Parser (line 71) | type Parser struct
    method nextToken (line 116) | func (p *Parser) nextToken() {
    method curTokenIs (line 121) | func (p *Parser) curTokenIs(t TokenType) bool {
    method peekTokenIs (line 125) | func (p *Parser) peekTokenIs(t TokenType) bool {
    method curPrecedence (line 129) | func (p *Parser) curPrecedence() precedence {
    method peekPrecedence (line 137) | func (p *Parser) peekPrecedence() precedence {
    method parseExpression (line 145) | func (p *Parser) parseExpression(prec precedence) (Expression, error) {
  function NewParser (line 77) | func NewParser(l *Lexer) *Parser {
  function ParseQuery (line 85) | func ParseQuery(input string) (expr Expression, err error) {
  function parsePrefixExpression (line 173) | func parsePrefixExpression(p *Parser) (Expression, error) {
  function parseInfixExpression (line 190) | func parseInfixExpression(p *Parser, left Expression) (Expression, error) {
  function parseStringLiteral (line 220) | func parseStringLiteral(p *Parser) (Expression, error) {
  function parseGroupedExpression (line 224) | func parseGroupedExpression(p *Parser) (Expression, error) {

FILE: pkg/filter/parser_test.go
  function TestParseQuery (line 10) | func TestParseQuery(t *testing.T) {
  function assertError (line 238) | func assertError(t *testing.T, exp, got error) {

FILE: pkg/log/log.go
  type Logger (line 11) | type Logger interface
  function NewZapLogger (line 17) | func NewZapLogger(verbose, jsonLogs bool) (*zap.Logger, error) {
  type NopLogger (line 79) | type NopLogger struct
    method Debugw (line 81) | func (nop NopLogger) Debugw(_ string, _ ...interface{}) {}
    method Infow (line 82) | func (nop NopLogger) Infow(_ string, _ ...interface{})  {}
    method Errorw (line 83) | func (nop NopLogger) Errorw(_ string, _ ...interface{}) {}
  function NewNopLogger (line 85) | func NewNopLogger() NopLogger {

FILE: pkg/proj/proj.go
  type Service (line 24) | type Service struct
    method CreateProject (line 90) | func (svc *Service) CreateProject(ctx context.Context, name string) (P...
    method CloseProject (line 109) | func (svc *Service) CloseProject() error {
    method DeleteProject (line 135) | func (svc *Service) DeleteProject(ctx context.Context, projectID ulid....
    method OpenProject (line 148) | func (svc *Service) OpenProject(ctx context.Context, projectID ulid.UL...
    method ActiveProject (line 190) | func (svc *Service) ActiveProject(ctx context.Context) (Project, error) {
    method Projects (line 206) | func (svc *Service) Projects(ctx context.Context) ([]Project, error) {
    method Scope (line 215) | func (svc *Service) Scope() *scope.Scope {
    method SetScopeRules (line 219) | func (svc *Service) SetScopeRules(ctx context.Context, rules []scope.R...
    method SetRequestLogFindFilter (line 237) | func (svc *Service) SetRequestLogFindFilter(ctx context.Context, filte...
    method SetSenderRequestFindFilter (line 258) | func (svc *Service) SetSenderRequestFindFilter(ctx context.Context, fi...
    method IsProjectActive (line 279) | func (svc *Service) IsProjectActive(projectID ulid.ULID) bool {
    method UpdateInterceptSettings (line 283) | func (svc *Service) UpdateInterceptSettings(ctx context.Context, setti...
  type Project (line 34) | type Project struct
  type Settings (line 42) | type Settings struct
  type Config (line 71) | type Config struct
  function NewService (line 80) | func NewService(cfg Config) (*Service, error) {

FILE: pkg/proj/repo.go
  type Repository (line 9) | type Repository interface

FILE: pkg/proxy/cert.go
  type CertConfig (line 29) | type CertConfig struct
    method TLSConfig (line 199) | func (c *CertConfig) TLSConfig() *tls.Config {
    method cert (line 213) | func (c *CertConfig) cert(hostname string) (*tls.Certificate, error) {
  function NewCertConfig (line 38) | func NewCertConfig(ca *x509.Certificate, caPrivKey crypto.PrivateKey) (*...
  function LoadOrCreateCA (line 67) | func LoadOrCreateCA(caKeyFile, caCertFile string) (*x509.Certificate, *r...
  function NewCA (line 141) | func NewCA(name, organization string, validity time.Duration) (*x509.Cer...

FILE: pkg/proxy/gzip.go
  function gunzipResponseBody (line 11) | func gunzipResponseBody(res *http.Response) error {

FILE: pkg/proxy/intercept/filter.go
  function MatchRequestFilter (line 71) | func MatchRequestFilter(req *http.Request, expr filter.Expression) (bool...
  function matchReqPrefixExpr (line 84) | func matchReqPrefixExpr(req *http.Request, expr filter.PrefixExpression)...
  function matchReqInfixExpr (line 98) | func matchReqInfixExpr(req *http.Request, expr filter.InfixExpression) (...
  function getMappedStringLiteralFromReq (line 191) | func getMappedStringLiteralFromReq(req *http.Request, s string) (string,...
  function matchReqStringLiteral (line 200) | func matchReqStringLiteral(req *http.Request, strLiteral filter.StringLi...
  function MatchRequestScope (line 226) | func MatchRequestScope(req *http.Request, s *scope.Scope) (bool, error) {
  function MatchResponseFilter (line 282) | func MatchResponseFilter(res *http.Response, expr filter.Expression) (bo...
  function matchResPrefixExpr (line 295) | func matchResPrefixExpr(res *http.Response, expr filter.PrefixExpression...
  function matchResInfixExpr (line 309) | func matchResInfixExpr(res *http.Response, expr filter.InfixExpression) ...
  function getMappedStringLiteralFromRes (line 402) | func getMappedStringLiteralFromRes(res *http.Response, s string) (string...
  function matchResStringLiteral (line 411) | func matchResStringLiteral(res *http.Response, strLiteral filter.StringL...

FILE: pkg/proxy/intercept/intercept.go
  type contextKey (line 25) | type contextKey
  constant interceptResponseKey (line 27) | interceptResponseKey contextKey = 0
  type Request (line 31) | type Request struct
  type Response (line 39) | type Response struct
  type Item (line 45) | type Item struct
  type Service (line 50) | type Service struct
    method RequestModifier (line 95) | func (svc *Service) RequestModifier(next proxy.RequestModifyFunc) prox...
    method InterceptRequest (line 125) | func (svc *Service) InterceptRequest(ctx context.Context, req *http.Re...
    method ModifyRequest (line 186) | func (svc *Service) ModifyRequest(reqID ulid.ULID, modReq *http.Reques...
    method CancelRequest (line 209) | func (svc *Service) CancelRequest(reqID ulid.ULID) error {
    method ClearRequests (line 213) | func (svc *Service) ClearRequests() {
    method ClearResponses (line 225) | func (svc *Service) ClearResponses() {
    method Items (line 238) | func (svc *Service) Items() []Item {
    method UpdateSettings (line 276) | func (svc *Service) UpdateSettings(settings Settings) {
    method ItemByID (line 294) | func (svc *Service) ItemByID(id ulid.ULID) (Item, error) {
    method ResponseModifier (line 343) | func (svc *Service) ResponseModifier(next proxy.ResponseModifyFunc) pr...
    method InterceptResponse (line 360) | func (svc *Service) InterceptResponse(ctx context.Context, res *http.R...
    method ModifyResponse (line 428) | func (svc *Service) ModifyResponse(reqID ulid.ULID, modRes *http.Respo...
    method CancelResponse (line 450) | func (svc *Service) CancelResponse(reqID ulid.ULID) error {
  type Config (line 63) | type Config struct
  type RequestIDs (line 72) | type RequestIDs
    method Len (line 321) | func (ids RequestIDs) Len() int {
    method Less (line 325) | func (ids RequestIDs) Less(i, j int) bool {
    method Swap (line 329) | func (ids RequestIDs) Swap(i, j int) {
  function NewService (line 74) | func NewService(cfg Config) *Service {
  function WithInterceptResponse (line 333) | func WithInterceptResponse(ctx context.Context, value bool) context.Cont...
  function ShouldInterceptResponseFromContext (line 337) | func ShouldInterceptResponseFromContext(ctx context.Context) (bool, bool) {

FILE: pkg/proxy/intercept/intercept_test.go
  function TestRequestModifier (line 23) | func TestRequestModifier(t *testing.T) {
  function TestResponseModifier (line 133) | func TestResponseModifier(t *testing.T) {

FILE: pkg/proxy/intercept/settings.go
  type Settings (line 5) | type Settings struct

FILE: pkg/proxy/modify.go
  type RequestModifyFunc (line 12) | type RequestModifyFunc
  type RequestModifyMiddleware (line 16) | type RequestModifyMiddleware
  type ResponseModifyFunc (line 20) | type ResponseModifyFunc
  type ResponseModifyMiddleware (line 24) | type ResponseModifyMiddleware

FILE: pkg/proxy/net.go
  type OnceAcceptListener (line 14) | type OnceAcceptListener struct
    method Accept (line 18) | func (l *OnceAcceptListener) Accept() (net.Conn, error) {
    method Close (line 29) | func (l *OnceAcceptListener) Close() error {
    method Addr (line 33) | func (l *OnceAcceptListener) Addr() net.Addr {
  type ConnNotify (line 39) | type ConnNotify struct
    method Close (line 44) | func (c *ConnNotify) Close() {

FILE: pkg/proxy/proxy.go
  type contextKey (line 25) | type contextKey
  constant reqIDKey (line 27) | reqIDKey contextKey = 0
  type Proxy (line 31) | type Proxy struct
    method ServeHTTP (line 92) | func (p *Proxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    method UseRequestModifier (line 105) | func (p *Proxy) UseRequestModifier(fn ...RequestModifyMiddleware) {
    method UseResponseModifier (line 109) | func (p *Proxy) UseResponseModifier(fn ...ResponseModifyMiddleware) {
    method modifyRequest (line 113) | func (p *Proxy) modifyRequest(r *http.Request) {
    method modifyResponse (line 152) | func (p *Proxy) modifyResponse(res *http.Response) error {
    method handleConnect (line 179) | func (p *Proxy) handleConnect(w http.ResponseWriter) {
    method clientTLSConn (line 223) | func (p *Proxy) clientTLSConn(conn net.Conn) (*tls.Conn, error) {
    method errorHandler (line 235) | func (p *Proxy) errorHandler(w http.ResponseWriter, r *http.Request, e...
  type Config (line 41) | type Config struct
  function NewProxy (line 48) | func NewProxy(cfg Config) (*Proxy, error) {
  function WithRequestID (line 167) | func WithRequestID(ctx context.Context, id ulid.ULID) context.Context {
  function RequestIDFromContext (line 171) | func RequestIDFromContext(ctx context.Context) (ulid.ULID, bool) {
  function writeError (line 247) | func writeError(w http.ResponseWriter, code int) {

FILE: pkg/reqlog/repo.go
  type Repository (line 11) | type Repository interface

FILE: pkg/reqlog/reqlog.go
  type contextKey (line 21) | type contextKey
  constant LogBypassedKey (line 24) | LogBypassedKey contextKey = iota
  constant ReqLogIDKey (line 25) | ReqLogIDKey
  type RequestLog (line 33) | type RequestLog struct
  type ResponseLog (line 46) | type ResponseLog struct
  type Service (line 54) | type Service struct
    method FindRequests (line 91) | func (svc *Service) FindRequests(ctx context.Context) ([]RequestLog, e...
    method FindRequestLogByID (line 95) | func (svc *Service) FindRequestLogByID(ctx context.Context, id ulid.UL...
    method ClearRequests (line 99) | func (svc *Service) ClearRequests(ctx context.Context, projectID ulid....
    method storeResponse (line 103) | func (svc *Service) storeResponse(ctx context.Context, reqLogID ulid.U...
    method RequestModifier (line 112) | func (svc *Service) RequestModifier(next proxy.RequestModifyFunc) prox...
    method ResponseModifier (line 190) | func (svc *Service) ResponseModifier(next proxy.ResponseModifyFunc) pr...
    method SetActiveProjectID (line 232) | func (svc *Service) SetActiveProjectID(id ulid.ULID) {
    method ActiveProjectID (line 236) | func (svc *Service) ActiveProjectID() ulid.ULID {
    method SetFindReqsFilter (line 240) | func (svc *Service) SetFindReqsFilter(filter FindRequestsFilter) {
    method FindReqsFilter (line 244) | func (svc *Service) FindReqsFilter() FindRequestsFilter {
    method SetBypassOutOfScopeRequests (line 248) | func (svc *Service) SetBypassOutOfScopeRequests(bypass bool) {
    method BypassOutOfScopeRequests (line 252) | func (svc *Service) BypassOutOfScopeRequests() bool {
  type FindRequestsFilter (line 63) | type FindRequestsFilter struct
  type Config (line 69) | type Config struct
  function NewService (line 76) | func NewService(cfg Config) *Service {
  function ParseHTTPResponse (line 256) | func ParseHTTPResponse(res *http.Response) (ResponseLog, error) {

FILE: pkg/reqlog/reqlog_test.go
  function TestRequestModifier (line 28) | func TestRequestModifier(t *testing.T) {
  function TestResponseModifier (line 89) | func TestResponseModifier(t *testing.T) {

FILE: pkg/reqlog/search.go
  method Matches (line 39) | func (reqLog RequestLog) Matches(expr filter.Expression) (bool, error) {
  method matchPrefixExpr (line 52) | func (reqLog RequestLog) matchPrefixExpr(expr filter.PrefixExpression) (...
  method matchInfixExpr (line 66) | func (reqLog RequestLog) matchInfixExpr(expr filter.InfixExpression) (bo...
  method getMappedStringLiteral (line 162) | func (reqLog RequestLog) getMappedStringLiteral(s string) string {
  method matchStringLiteral (line 183) | func (reqLog RequestLog) matchStringLiteral(strLiteral filter.StringLite...
  method MatchScope (line 229) | func (reqLog RequestLog) MatchScope(s *scope.Scope) bool {

FILE: pkg/reqlog/search_test.go
  function TestRequestLogMatch (line 10) | func TestRequestLogMatch(t *testing.T) {
  function assertError (line 192) | func assertError(t *testing.T, exp, got error) {

FILE: pkg/scope/scope.go
  type Scope (line 11) | type Scope struct
    method Rules (line 27) | func (s *Scope) Rules() []Rule {
    method SetRules (line 34) | func (s *Scope) SetRules(rules []Rule) {
    method Match (line 41) | func (s *Scope) Match(req *http.Request, body []byte) bool {
  type Rule (line 16) | type Rule struct
    method Match (line 54) | func (r Rule) Match(req *http.Request, body []byte) bool {
    method MarshalBinary (line 124) | func (r Rule) MarshalBinary() ([]byte, error) {
    method UnmarshalBinary (line 142) | func (r *Rule) UnmarshalBinary(data []byte) error {
  type Header (line 22) | type Header struct
  function regexpToString (line 99) | func regexpToString(r *regexp.Regexp) string {
  function stringToRegexp (line 107) | func stringToRegexp(s string) (*regexp.Regexp, error) {
  type ruleDTO (line 115) | type ruleDTO struct

FILE: pkg/sender/repo.go
  type Repository (line 11) | type Repository interface

FILE: pkg/sender/search.go
  method Matches (line 32) | func (req Request) Matches(expr filter.Expression) (bool, error) {
  method matchPrefixExpr (line 45) | func (req Request) matchPrefixExpr(expr filter.PrefixExpression) (bool, ...
  method matchInfixExpr (line 59) | func (req Request) matchInfixExpr(expr filter.InfixExpression) (bool, er...
  method getMappedStringLiteral (line 155) | func (req Request) getMappedStringLiteral(s string) string {
  method matchStringLiteral (line 176) | func (req Request) matchStringLiteral(strLiteral filter.StringLiteral) (...
  method MatchScope (line 222) | func (req Request) MatchScope(s *scope.Scope) bool {

FILE: pkg/sender/search_test.go
  function TestRequestLogMatch (line 11) | func TestRequestLogMatch(t *testing.T) {
  function assertError (line 193) | func assertError(t *testing.T, exp, got error) {

FILE: pkg/sender/sender.go
  type Service (line 33) | type Service struct
    method FindRequestByID (line 88) | func (svc *Service) FindRequestByID(ctx context.Context, id ulid.ULID)...
    method FindRequests (line 97) | func (svc *Service) FindRequests(ctx context.Context) ([]Request, erro...
    method CreateOrUpdateRequest (line 101) | func (svc *Service) CreateOrUpdateRequest(ctx context.Context, req Req...
    method CloneFromRequestLog (line 132) | func (svc *Service) CloneFromRequestLog(ctx context.Context, reqLogID ...
    method SetFindReqsFilter (line 161) | func (svc *Service) SetFindReqsFilter(filter FindRequestsFilter) {
    method FindReqsFilter (line 165) | func (svc *Service) FindReqsFilter() FindRequestsFilter {
    method SendRequest (line 169) | func (svc *Service) SendRequest(ctx context.Context, id ulid.ULID) (Re...
    method sendHTTPRequest (line 212) | func (svc *Service) sendHTTPRequest(httpReq *http.Request) (reqlog.Res...
    method SetActiveProjectID (line 227) | func (svc *Service) SetActiveProjectID(id ulid.ULID) {
    method DeleteRequests (line 231) | func (svc *Service) DeleteRequests(ctx context.Context, projectID ulid...
  type FindRequestsFilter (line 42) | type FindRequestsFilter struct
  type Config (line 48) | type Config struct
  type SendError (line 55) | type SendError struct
    method Error (line 235) | func (e SendError) Error() string {
    method Unwrap (line 239) | func (e SendError) Unwrap() error {
  function NewService (line 59) | func NewService(cfg Config) *Service {
  type Request (line 74) | type Request struct
  function parseHTTPRequest (line 197) | func parseHTTPRequest(ctx context.Context, req Request) (*http.Request, ...

FILE: pkg/sender/sender_test.go
  function TestStoreRequest (line 37) | func TestStoreRequest(t *testing.T) {
  function TestCloneFromRequestLog (line 133) | func TestCloneFromRequestLog(t *testing.T) {
  function TestSendRequest (line 223) | func TestSendRequest(t *testing.T) {

FILE: pkg/sender/transport.go
  type HTTPTransport (line 10) | type HTTPTransport struct
    method RoundTrip (line 39) | func (t *HTTPTransport) RoundTrip(req *http.Request) (*http.Response, ...
  type protoCtxKey (line 12) | type protoCtxKey struct
  constant HTTPProto10 (line 15) | HTTPProto10 = "HTTP/1.0"
  constant HTTPProto11 (line 16) | HTTPProto11 = "HTTP/1.1"
  constant HTTPProto20 (line 17) | HTTPProto20 = "HTTP/2.0"
  function isValidProto (line 49) | func isValidProto(proto string) bool {
Condensed preview — 161 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (773K chars).
[
  {
    "path": ".dockerignore",
    "chars": 92,
    "preview": "/admin/.env\n/admin/.next\n/admin/dist\n/admin/node_modules\n/dist\n/docs\n/hetty\n/cmd/hetty/admin"
  },
  {
    "path": ".github/FUNDING.yml",
    "chars": 86,
    "preview": "github: dstotijn\npatreon: dstotijn\ncustom: \"https://www.paypal.com/paypalme/dstotijn\"\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "chars": 834,
    "preview": "---\nname: Bug report\nabout: Create a report to help us improve\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\n**Describe the b"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/config.yml",
    "chars": 189,
    "preview": "blank_issues_enabled: false\ncontact_links:\n  - name: Ask a question\n    url: https://github.com/dstotijn/hetty/discussio"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.md",
    "chars": 595,
    "preview": "---\nname: Feature request\nabout: Suggest an idea for this project\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\n**Is your fea"
  },
  {
    "path": ".github/workflows/build-test.yml",
    "chars": 1539,
    "preview": "name: Build and Test\non: [push, pull_request]\njobs:\n  build:\n    runs-on: ubuntu-latest\n    strategy:\n      matrix:\n    "
  },
  {
    "path": ".github/workflows/lint.yml",
    "chars": 333,
    "preview": "name: Lint\non: [push, pull_request]\ndefaults:\n  run:\n    working-directory: ./admin\njobs:\n  lint-admin:\n    runs-on: ubu"
  },
  {
    "path": ".gitignore",
    "chars": 51,
    "preview": "*.vscode\n/dist\n/hetty\n/cmd/hetty/admin\n*.pem\n*.test"
  },
  {
    "path": ".golangci.yml",
    "chars": 1120,
    "preview": "linters:\n  presets:\n    - bugs\n    - comment\n    - error\n    - format\n    - import\n    - metalinter\n    - module\n    - p"
  },
  {
    "path": ".goreleaser.yml",
    "chars": 2595,
    "preview": "before:\n  hooks:\n    - make clean\n    - sh -c \"NEXT_PUBLIC_VERSION={{ .Version}} make build-admin\"\n    - go mod tidy\n\nbu"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "chars": 3350,
    "preview": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nIn the interest of fostering an open and welcoming environment, w"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 1605,
    "preview": "# Contribution Guidelines\n\nThank you for taking an interest in Hetty! If you want to contribute to the\nproject, please r"
  },
  {
    "path": "Dockerfile",
    "chars": 691,
    "preview": "ARG GO_VERSION=1.17\nARG NODE_VERSION=16.13\nARG ALPINE_VERSION=3.15\n\nFROM node:${NODE_VERSION}-alpine AS node-builder\nWOR"
  },
  {
    "path": "LICENSE",
    "chars": 1070,
    "preview": "MIT License\n\nCopyright (c) 2021 David Stotijn\n\nPermission is hereby granted, free of charge, to any person obtaining a c"
  },
  {
    "path": "Makefile",
    "chars": 356,
    "preview": "export CGO_ENABLED = 0\nexport NEXT_TELEMETRY_DISABLED = 1\n\n.PHONY: build\nbuild: build-admin\n\tgo build ./cmd/hetty\n\n.PHON"
  },
  {
    "path": "README.md",
    "chars": 5414,
    "preview": "<img src=\"https://user-images.githubusercontent.com/983924/156430531-6193e187-7400-436b-81c6-f86862783ea5.svg#gh-light-m"
  },
  {
    "path": "admin/.eslintrc.json",
    "chars": 1475,
    "preview": "{\n  \"root\": true,\n  \"extends\": [\"next/core-web-vitals\", \"prettier\", \"plugin:@typescript-eslint/recommended\", \"plugin:imp"
  },
  {
    "path": "admin/.gitignore",
    "chars": 35,
    "preview": "/node_modules\n/.next\n/dist\n\n*.log*\n"
  },
  {
    "path": "admin/.prettierignore",
    "chars": 31,
    "preview": "/.next/\n/out/\n/build\n/coverage\n"
  },
  {
    "path": "admin/.prettierrc.json",
    "chars": 26,
    "preview": "{\n    \"printWidth\": 120\n}\n"
  },
  {
    "path": "admin/gqlcodegen.yml",
    "chars": 226,
    "preview": "overwrite: true\nschema: \"../pkg/api/schema.graphql\"\ndocuments: \"src/**/*.graphql\"\ngenerates:\n  src/lib/graphql/generated"
  },
  {
    "path": "admin/next-env.d.ts",
    "chars": 201,
    "preview": "/// <reference types=\"next\" />\n/// <reference types=\"next/image-types/global\" />\n\n// NOTE: This file should not be edite"
  },
  {
    "path": "admin/next.config.js",
    "chars": 313,
    "preview": "// @ts-check\n\n/**\n * @type {import('next').NextConfig}\n **/\nconst nextConfig = {\n  reactStrictMode: true,\n  trailingSlas"
  },
  {
    "path": "admin/package.json",
    "chars": 1701,
    "preview": "{\n  \"name\": \"hetty-admin\",\n  \"version\": \"0.1.0\",\n  \"private\": true,\n  \"scripts\": {\n    \"dev\": \"next dev\",\n    \"build\": \""
  },
  {
    "path": "admin/public/site.webmanifest",
    "chars": 263,
    "preview": "{\"name\":\"\",\"short_name\":\"\",\"icons\":[{\"src\":\"/android-chrome-192x192.png\",\"sizes\":\"192x192\",\"type\":\"image/png\"},{\"src\":\"/"
  },
  {
    "path": "admin/public/style.css",
    "chars": 2973,
    "preview": "@font-face {\n  font-family: \"JetBrains Mono\";\n  src: url(\"https://cdn.jsdelivr.net/gh/JetBrains/JetBrainsMono/web/woff2/"
  },
  {
    "path": "admin/src/features/Layout.tsx",
    "chars": 8228,
    "preview": "import AltRouteIcon from \"@mui/icons-material/AltRoute\";\nimport ChevronLeftIcon from \"@mui/icons-material/ChevronLeft\";\n"
  },
  {
    "path": "admin/src/features/intercept/components/EditRequest.tsx",
    "chars": 13228,
    "preview": "import CancelIcon from \"@mui/icons-material/Cancel\";\nimport DownloadIcon from \"@mui/icons-material/Download\";\nimport Sen"
  },
  {
    "path": "admin/src/features/intercept/components/Intercept.tsx",
    "chars": 555,
    "preview": "import { Box } from \"@mui/material\";\n\nimport EditRequest from \"./EditRequest\";\nimport Requests from \"./Requests\";\n\nimpor"
  },
  {
    "path": "admin/src/features/intercept/components/Requests.tsx",
    "chars": 995,
    "preview": "import { Box, Paper, Typography } from \"@mui/material\";\nimport { useRouter } from \"next/router\";\n\nimport { useIntercepte"
  },
  {
    "path": "admin/src/features/intercept/graphql/cancelRequest.graphql",
    "chars": 80,
    "preview": "mutation CancelRequest($id: ID!) {\n  cancelRequest(id: $id) {\n    success\n  }\n}\n"
  },
  {
    "path": "admin/src/features/intercept/graphql/cancelResponse.graphql",
    "chars": 103,
    "preview": "mutation CancelResponse($requestID: ID!) {\n  cancelResponse(requestID: $requestID) {\n    success\n  }\n}\n"
  },
  {
    "path": "admin/src/features/intercept/graphql/interceptedRequest.graphql",
    "chars": 304,
    "preview": "query GetInterceptedRequest($id: ID!) {\n  interceptedRequest(id: $id) {\n    id\n    url\n    method\n    proto\n    headers "
  },
  {
    "path": "admin/src/features/intercept/graphql/modifyRequest.graphql",
    "chars": 111,
    "preview": "mutation ModifyRequest($request: ModifyRequestInput!) {\n  modifyRequest(request: $request) {\n    success\n  }\n}\n"
  },
  {
    "path": "admin/src/features/intercept/graphql/modifyResponse.graphql",
    "chars": 117,
    "preview": "mutation ModifyResponse($response: ModifyResponseInput!) {\n  modifyResponse(response: $response) {\n    success\n  }\n}\n"
  },
  {
    "path": "admin/src/features/projects/components/NewProject.tsx",
    "chars": 2025,
    "preview": "import AddIcon from \"@mui/icons-material/Add\";\nimport { Box, Button, CircularProgress, TextField, Typography } from \"@mu"
  },
  {
    "path": "admin/src/features/projects/components/ProjectList.tsx",
    "chars": 7405,
    "preview": "import CloseIcon from \"@mui/icons-material/Close\";\nimport DeleteIcon from \"@mui/icons-material/Delete\";\nimport Descripti"
  },
  {
    "path": "admin/src/features/projects/graphql/activeProject.graphql",
    "chars": 216,
    "preview": "query ActiveProject {\n  activeProject {\n    id\n    name\n    isActive\n    settings {\n      intercept {\n        requestsEn"
  },
  {
    "path": "admin/src/features/projects/graphql/closeProject.graphql",
    "chars": 59,
    "preview": "mutation CloseProject {\n  closeProject {\n    success\n  }\n}\n"
  },
  {
    "path": "admin/src/features/projects/graphql/createProject.graphql",
    "chars": 94,
    "preview": "mutation CreateProject($name: String!) {\n  createProject(name: $name) {\n    id\n    name\n  }\n}\n"
  },
  {
    "path": "admin/src/features/projects/graphql/deleteProject.graphql",
    "chars": 80,
    "preview": "mutation DeleteProject($id: ID!) {\n  deleteProject(id: $id) {\n    success\n  }\n}\n"
  },
  {
    "path": "admin/src/features/projects/graphql/openProject.graphql",
    "chars": 93,
    "preview": "mutation OpenProject($id: ID!) {\n  openProject(id: $id) {\n    id\n    name\n    isActive\n  }\n}\n"
  },
  {
    "path": "admin/src/features/projects/graphql/projects.graphql",
    "chars": 65,
    "preview": "query Projects {\n  projects {\n    id\n    name\n    isActive\n  }\n}\n"
  },
  {
    "path": "admin/src/features/projects/hooks/useOpenProjectMutation.ts",
    "chars": 1244,
    "preview": "import { gql } from \"@apollo/client\";\n\nimport { useOpenProjectMutation as _useOpenProjectMutation } from \"lib/graphql/ge"
  },
  {
    "path": "admin/src/features/reqlog/components/Actions.tsx",
    "chars": 2225,
    "preview": "import AltRouteIcon from \"@mui/icons-material/AltRoute\";\nimport DeleteIcon from \"@mui/icons-material/Delete\";\nimport { A"
  },
  {
    "path": "admin/src/features/reqlog/components/LogDetail.tsx",
    "chars": 1385,
    "preview": "import Alert from \"@mui/lab/Alert\";\nimport { Box, CircularProgress, Paper, Typography } from \"@mui/material\";\n\nimport Re"
  },
  {
    "path": "admin/src/features/reqlog/components/RequestDetail.tsx",
    "chars": 1403,
    "preview": "import { Typography, Box } from \"@mui/material\";\nimport React from \"react\";\n\nimport RequestTabs from \"lib/components/Req"
  },
  {
    "path": "admin/src/features/reqlog/components/RequestLogs.tsx",
    "chars": 4088,
    "preview": "import ContentCopyIcon from \"@mui/icons-material/ContentCopy\";\nimport {\n  Alert,\n  Box,\n  IconButton,\n  Link,\n  MenuItem"
  },
  {
    "path": "admin/src/features/reqlog/components/Search.tsx",
    "chars": 5072,
    "preview": "import FilterListIcon from \"@mui/icons-material/FilterList\";\nimport SearchIcon from \"@mui/icons-material/Search\";\nimport"
  },
  {
    "path": "admin/src/features/reqlog/graphql/clearHttpRequestLog.graphql",
    "chars": 73,
    "preview": "mutation ClearHTTPRequestLog {\n  clearHTTPRequestLog {\n    success\n  }\n}\n"
  },
  {
    "path": "admin/src/features/reqlog/graphql/httpRequestLog.graphql",
    "chars": 293,
    "preview": "query HttpRequestLog($id: ID!) {\n  httpRequestLog(id: $id) {\n    id\n    method\n    url\n    proto\n    headers {\n      key"
  },
  {
    "path": "admin/src/features/reqlog/graphql/httpRequestLogFilter.graphql",
    "chars": 97,
    "preview": "query HttpRequestLogFilter {\n  httpRequestLogFilter {\n    onlyInScope\n    searchExpression\n  }\n}\n"
  },
  {
    "path": "admin/src/features/reqlog/graphql/httpRequestLogs.graphql",
    "chars": 147,
    "preview": "query HttpRequestLogs {\n  httpRequestLogs {\n    id\n    method\n    url\n    timestamp\n    response {\n      statusCode\n    "
  },
  {
    "path": "admin/src/features/reqlog/graphql/setHttpRequestLogFilter.graphql",
    "chars": 159,
    "preview": "mutation SetHttpRequestLogFilter($filter: HttpRequestLogFilterInput) {\n  setHttpRequestLogFilter(filter: $filter) {\n    "
  },
  {
    "path": "admin/src/features/reqlog/index.ts",
    "chars": 85,
    "preview": "import { RequestLogs } from \"./components/RequestLogs\";\n\nexport default RequestLogs;\n"
  },
  {
    "path": "admin/src/features/scope/components/AddRule.tsx",
    "chars": 2890,
    "preview": "import { useApolloClient } from \"@apollo/client\";\nimport AddIcon from \"@mui/icons-material/Add\";\nimport { Alert } from \""
  },
  {
    "path": "admin/src/features/scope/components/RuleListItem.tsx",
    "chars": 2135,
    "preview": "import { useApolloClient } from \"@apollo/client\";\nimport CodeIcon from \"@mui/icons-material/Code\";\nimport DeleteIcon fro"
  },
  {
    "path": "admin/src/features/scope/components/Rules.tsx",
    "chars": 798,
    "preview": "import { Alert } from \"@mui/lab\";\nimport { CircularProgress, List } from \"@mui/material\";\nimport React from \"react\";\n\nim"
  },
  {
    "path": "admin/src/features/scope/graphql/scope.graphql",
    "chars": 38,
    "preview": "query Scope {\n  scope {\n    url\n  }\n}\n"
  },
  {
    "path": "admin/src/features/scope/graphql/setScope.graphql",
    "chars": 90,
    "preview": "mutation SetScope($scope: [ScopeRuleInput!]!) {\n  setScope(scope: $scope) {\n    url\n  }\n}\n"
  },
  {
    "path": "admin/src/features/sender/components/EditRequest.tsx",
    "chars": 7364,
    "preview": "import AddIcon from \"@mui/icons-material/Add\";\nimport { Alert, Box, Button, Fab, Tooltip, Typography, useTheme } from \"@"
  },
  {
    "path": "admin/src/features/sender/components/History.tsx",
    "chars": 1026,
    "preview": "import { Box, Paper, Typography } from \"@mui/material\";\nimport { useRouter } from \"next/router\";\n\nimport RequestsTable f"
  },
  {
    "path": "admin/src/features/sender/components/Sender.tsx",
    "chars": 552,
    "preview": "import { Box } from \"@mui/material\";\n\nimport EditRequest from \"./EditRequest\";\nimport History from \"./History\";\n\nimport "
  },
  {
    "path": "admin/src/features/sender/graphql/createOrUpdateRequest.graphql",
    "chars": 134,
    "preview": "mutation CreateOrUpdateSenderRequest($request: SenderRequestInput!) {\n  createOrUpdateSenderRequest(request: $request) {"
  },
  {
    "path": "admin/src/features/sender/graphql/createSenderRequestFromRequestLog.graphql",
    "chars": 123,
    "preview": "mutation CreateSenderRequestFromHttpRequestLog($id: ID!) {\n  createSenderRequestFromHttpRequestLog(id: $id) {\n    id\n  }"
  },
  {
    "path": "admin/src/features/sender/graphql/sendRequest.graphql",
    "chars": 71,
    "preview": "mutation SendRequest($id: ID!) {\n  sendRequest(id: $id) {\n    id\n  }\n}\n"
  },
  {
    "path": "admin/src/features/sender/graphql/senderRequest.graphql",
    "chars": 331,
    "preview": "query GetSenderRequest($id: ID!) {\n  senderRequest(id: $id) {\n    id\n    sourceRequestLogID\n    url\n    method\n    proto"
  },
  {
    "path": "admin/src/features/sender/graphql/senderRequests.graphql",
    "chars": 143,
    "preview": "query GetSenderRequests {\n  senderRequests {\n    id\n    url\n    method\n    response {\n      id\n      statusCode\n      st"
  },
  {
    "path": "admin/src/features/sender/index.ts",
    "chars": 66,
    "preview": "import Sender from \"./components/Sender\";\n\nexport default Sender;\n"
  },
  {
    "path": "admin/src/features/settings/components/Settings.tsx",
    "chars": 10154,
    "preview": "import { useApolloClient } from \"@apollo/client\";\nimport { TabContext, TabPanel } from \"@mui/lab\";\nimport TabList from \""
  },
  {
    "path": "admin/src/features/settings/graphql/updateInterceptSettings.graphql",
    "chars": 201,
    "preview": "mutation UpdateInterceptSettings($input: UpdateInterceptSettingsInput!) {\n  updateInterceptSettings(input: $input) {\n   "
  },
  {
    "path": "admin/src/lib/ActiveProjectContext.tsx",
    "chars": 611,
    "preview": "import React, { createContext, useContext } from \"react\";\n\nimport { Project, useActiveProjectQuery } from \"./graphql/gen"
  },
  {
    "path": "admin/src/lib/InterceptedRequestsContext.tsx",
    "chars": 757,
    "preview": "import React, { createContext, useContext } from \"react\";\n\nimport { GetInterceptedRequestsQuery, useGetInterceptedReques"
  },
  {
    "path": "admin/src/lib/components/ConfirmationDialog.tsx",
    "chars": 1445,
    "preview": "import Button from \"@mui/material/Button\";\nimport Dialog from \"@mui/material/Dialog\";\nimport DialogActions from \"@mui/ma"
  },
  {
    "path": "admin/src/lib/components/Editor.tsx",
    "chars": 1172,
    "preview": "import MonacoEditor, { EditorProps } from \"@monaco-editor/react\";\n\nconst defaultMonacoOptions: EditorProps[\"options\"] = "
  },
  {
    "path": "admin/src/lib/components/HttpStatusIcon.tsx",
    "chars": 606,
    "preview": "import FiberManualRecordIcon from \"@mui/icons-material/FiberManualRecord\";\nimport { SvgIconTypeMap } from \"@mui/material"
  },
  {
    "path": "admin/src/lib/components/KeyValuePair.tsx",
    "chars": 5286,
    "preview": "import ClearIcon from \"@mui/icons-material/Clear\";\nimport {\n  Alert,\n  IconButton,\n  InputBase,\n  InputBaseProps,\n  Snac"
  },
  {
    "path": "admin/src/lib/components/Link.tsx",
    "chars": 2772,
    "preview": "import MuiLink, { LinkProps as MuiLinkProps } from \"@mui/material/Link\";\nimport { styled } from \"@mui/material/styles\";\n"
  },
  {
    "path": "admin/src/lib/components/RequestTabs.tsx",
    "chars": 3170,
    "preview": "import { TabContext, TabList, TabPanel } from \"@mui/lab\";\nimport { Box, Tab } from \"@mui/material\";\nimport React, { useS"
  },
  {
    "path": "admin/src/lib/components/RequestsTable.tsx",
    "chars": 3279,
    "preview": "import {\n  TableContainer,\n  Table,\n  TableHead,\n  TableRow,\n  TableCell,\n  TableBody,\n  styled,\n  TableCellProps,\n  Tab"
  },
  {
    "path": "admin/src/lib/components/Response.tsx",
    "chars": 1072,
    "preview": "import { Box, Typography } from \"@mui/material\";\n\nimport ResponseTabs from \"./ResponseTabs\";\n\nimport ResponseStatus from"
  },
  {
    "path": "admin/src/lib/components/ResponseStatus.tsx",
    "chars": 1083,
    "preview": "import { Typography } from \"@mui/material\";\n\nimport HttpStatusIcon from \"./HttpStatusIcon\";\n\nimport { HttpProtocol } fro"
  },
  {
    "path": "admin/src/lib/components/ResponseTabs.tsx",
    "chars": 2702,
    "preview": "import { TabContext, TabList, TabPanel } from \"@mui/lab\";\nimport { Box, Paper, Tab, Typography } from \"@mui/material\";\ni"
  },
  {
    "path": "admin/src/lib/components/SplitPane.tsx",
    "chars": 1584,
    "preview": "import { alpha, styled } from \"@mui/material/styles\";\nimport ReactSplitPane, { SplitPaneProps } from \"react-split-pane\";"
  },
  {
    "path": "admin/src/lib/components/UrlBar.tsx",
    "chars": 3378,
    "preview": "import { Box, BoxProps, FormControl, InputLabel, MenuItem, Select, TextField } from \"@mui/material\";\n\nimport { HttpProto"
  },
  {
    "path": "admin/src/lib/components/useContextMenu.tsx",
    "chars": 1365,
    "preview": "import { Menu } from \"@mui/material\";\nimport React, { useState } from \"react\";\n\ninterface ContextMenuProps {\n  children?"
  },
  {
    "path": "admin/src/lib/graphql/generated.tsx",
    "chars": 61301,
    "preview": "import { gql } from '@apollo/client';\nimport * as Apollo from '@apollo/client';\nexport type Maybe<T> = T | null;\nexport "
  },
  {
    "path": "admin/src/lib/graphql/interceptedRequests.graphql",
    "chars": 144,
    "preview": "query GetInterceptedRequests {\n  interceptedRequests {\n    id\n    url\n    method\n    response {\n      statusCode\n      s"
  },
  {
    "path": "admin/src/lib/graphql/omitTypename.ts",
    "chars": 229,
    "preview": "function omitTypename<T>(key: string, value: T): T | undefined {\n  return key === \"__typename\" ? undefined : value;\n}\n\ne"
  },
  {
    "path": "admin/src/lib/graphql/useApollo.ts",
    "chars": 987,
    "preview": "import { ApolloClient, HttpLink, InMemoryCache, NormalizedCacheObject } from \"@apollo/client\";\n\nlet apolloClient: Apollo"
  },
  {
    "path": "admin/src/lib/mui/createEmotionCache.ts",
    "chars": 331,
    "preview": "import createCache from \"@emotion/cache\";\n\n// prepend: true moves MUI styles to the top of the <head> so they're loaded "
  },
  {
    "path": "admin/src/lib/mui/theme.ts",
    "chars": 1450,
    "preview": "import * as colors from \"@mui/material/colors\";\nimport { createTheme } from \"@mui/material/styles\";\n\ndeclare module \"@mu"
  },
  {
    "path": "admin/src/lib/queryParamsFromURL.tsx",
    "chars": 458,
    "preview": "import { KeyValuePair } from \"./components/KeyValuePair\";\n\nexport function queryParamsFromURL(url: string): KeyValuePair"
  },
  {
    "path": "admin/src/lib/updateKeyPairItem.ts",
    "chars": 512,
    "preview": "import { KeyValuePair } from \"./components/KeyValuePair\";\n\nfunction updateKeyPairItem(key: string, value: string, idx: n"
  },
  {
    "path": "admin/src/lib/updateURLQueryParams.ts",
    "chars": 827,
    "preview": "import { KeyValuePair } from \"./components/KeyValuePair\";\n\nfunction updateURLQueryParams(url: string, queryParams: KeyVa"
  },
  {
    "path": "admin/src/pages/_app.tsx",
    "chars": 1576,
    "preview": "import { ApolloProvider } from \"@apollo/client\";\nimport { CacheProvider, EmotionCache } from \"@emotion/react\";\nimport { "
  },
  {
    "path": "admin/src/pages/_document.tsx",
    "chars": 2690,
    "preview": "import createEmotionServer from \"@emotion/server/create-instance\";\nimport Document, { Html, Head, Main, NextScript } fro"
  },
  {
    "path": "admin/src/pages/index.tsx",
    "chars": 1354,
    "preview": "import FolderIcon from \"@mui/icons-material/Folder\";\nimport { Box, Button, Typography } from \"@mui/material\";\nimport Lin"
  },
  {
    "path": "admin/src/pages/projects/index.tsx",
    "chars": 941,
    "preview": "import { Box, Divider, Grid, Typography } from \"@mui/material\";\n\nimport { Layout, Page } from \"features/Layout\";\nimport "
  },
  {
    "path": "admin/src/pages/proxy/index.tsx",
    "chars": 603,
    "preview": "import ListIcon from \"@mui/icons-material/List\";\nimport { Button, Typography } from \"@mui/material\";\nimport Link from \"n"
  },
  {
    "path": "admin/src/pages/proxy/intercept/index.tsx",
    "chars": 298,
    "preview": "import { Layout, Page } from \"features/Layout\";\nimport Intercept from \"features/intercept/components/Intercept\";\n\nfuncti"
  },
  {
    "path": "admin/src/pages/proxy/logs/index.tsx",
    "chars": 263,
    "preview": "import { Layout, Page } from \"features/Layout\";\nimport RequestLogs from \"features/reqlog\";\n\nfunction ProxyLogs(): JSX.El"
  },
  {
    "path": "admin/src/pages/scope/index.tsx",
    "chars": 1165,
    "preview": "import { Box, Divider, Grid, Typography } from \"@mui/material\";\nimport React from \"react\";\n\nimport { Layout, Page } from"
  },
  {
    "path": "admin/src/pages/sender/index.tsx",
    "chars": 238,
    "preview": "import { Layout, Page } from \"features/Layout\";\nimport Sender from \"features/sender\";\n\nfunction Index(): JSX.Element {\n "
  },
  {
    "path": "admin/src/pages/settings/index.tsx",
    "chars": 268,
    "preview": "import { Layout, Page } from \"features/Layout\";\nimport Settings from \"features/settings/components/Settings\";\n\nfunction "
  },
  {
    "path": "admin/src/styles.css",
    "chars": 40,
    "preview": "html,\nbody,\n#__next {\n  height: 100%;\n}\n"
  },
  {
    "path": "admin/tsconfig.json",
    "chars": 612,
    "preview": "{\n  \"compilerOptions\": {\n    \"target\": \"es5\",\n    \"lib\": [\"dom\", \"dom.iterable\", \"esnext\"],\n    \"baseUrl\": \"src\",\n    \"p"
  },
  {
    "path": "cmd/hetty/cert.go",
    "chars": 5823,
    "preview": "package main\n\nimport (\n\t\"context\"\n\t\"flag\"\n\t\"fmt\"\n\n\t\"github.com/mitchellh/go-homedir\"\n\t\"github.com/peterbourgon/ff/v3/ffc"
  },
  {
    "path": "cmd/hetty/config.go",
    "chars": 694,
    "preview": "package main\n\nimport (\n\t\"flag\"\n\n\t\"go.uber.org/zap\"\n)\n\n// Config represents the global configuration shared amongst all c"
  },
  {
    "path": "cmd/hetty/hetty.go",
    "chars": 9278,
    "preview": "package main\n\nimport (\n\t\"context\"\n\t\"crypto/tls\"\n\t\"embed\"\n\t\"errors\"\n\t\"flag\"\n\t\"fmt\"\n\t\"io/fs\"\n\t\"net\"\n\t\"net/http\"\n\t\"os\"\n\t\"os"
  },
  {
    "path": "cmd/hetty/main.go",
    "chars": 612,
    "preview": "package main\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"flag\"\n\tllog \"log\"\n\t\"os\"\n\n\t\"go.uber.org/zap\"\n\n\t\"github.com/dstotijn/hetty/p"
  },
  {
    "path": "go.mod",
    "chars": 1800,
    "preview": "module github.com/dstotijn/hetty\n\ngo 1.23\n\ntoolchain go1.23.4\n\nrequire (\n\tgithub.com/99designs/gqlgen v0.14.0\n\tgithub.co"
  },
  {
    "path": "go.sum",
    "chars": 17880,
    "preview": "github.com/99designs/gqlgen v0.14.0 h1:Wg8aNYQUjMR/4v+W3xD+7SizOy6lSvVeQ06AobNQAXI=\ngithub.com/99designs/gqlgen v0.14.0/"
  },
  {
    "path": "gqlgen.yml",
    "chars": 1631,
    "preview": "# Where are all the schema files located? globs are supported eg  src/**/*.graphqls\nschema:\n  - pkg/api/schema.graphql\n\n"
  },
  {
    "path": "pkg/api/generated.go",
    "chars": 251079,
    "preview": "// Code generated by github.com/99designs/gqlgen, DO NOT EDIT.\n\npackage api\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"errors\"\n\t\"ne"
  },
  {
    "path": "pkg/api/http.go",
    "chars": 502,
    "preview": "package api\n\nimport (\n\t\"net/http\"\n\n\t\"github.com/99designs/gqlgen/graphql/handler\"\n\t\"github.com/99designs/gqlgen/graphql/"
  },
  {
    "path": "pkg/api/models.go",
    "chars": 1195,
    "preview": "package api\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/url\"\n\t\"strconv\"\n\n\t\"github.com/99designs/gqlgen/graphql\"\n\t\"github.com/oklog/ulid"
  },
  {
    "path": "pkg/api/models_gen.go",
    "chars": 7641,
    "preview": "// Code generated by github.com/99designs/gqlgen, DO NOT EDIT.\n\npackage api\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/url\"\n\t\"strconv\""
  },
  {
    "path": "pkg/api/resolvers.go",
    "chars": 25409,
    "preview": "package api\n\n//go:generate go run github.com/99designs/gqlgen\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"io/"
  },
  {
    "path": "pkg/api/schema.graphql",
    "chars": 4528,
    "preview": "type HttpRequestLog {\n  id: ID!\n  url: String!\n  method: HttpMethod!\n  proto: String!\n  headers: [HttpHeader!]!\n  body: "
  },
  {
    "path": "pkg/chrome/chrome.go",
    "chars": 981,
    "preview": "package chrome\n\nimport (\n\t\"context\"\n\t\"strings\"\n\n\t\"github.com/chromedp/chromedp\"\n)\n\nvar defaultOpts = []chromedp.ExecAllo"
  },
  {
    "path": "pkg/db/bolt/bolt.go",
    "chars": 1375,
    "preview": "package bolt\n\nimport (\n\t\"fmt\"\n\n\tbolt \"go.etcd.io/bbolt\"\n)\n\n// Database is used to store and retrieve data from an underl"
  },
  {
    "path": "pkg/db/bolt/logger.go",
    "chars": 391,
    "preview": "package bolt\n\nimport (\n\tbolt \"go.etcd.io/bbolt\"\n\t\"go.uber.org/zap\"\n)\n\n// Interface guard.\nvar _ bolt.Logger = (*Logger)("
  },
  {
    "path": "pkg/db/bolt/proj.go",
    "chars": 4026,
    "preview": "package bolt\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/gob\"\n\t\"errors\"\n\t\"fmt\"\n\n\t\"github.com/oklog/ulid\"\n\tbolt \"go.etcd.io/"
  },
  {
    "path": "pkg/db/bolt/proj_test.go",
    "chars": 6423,
    "preview": "package bolt_test\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/gob\"\n\t\"errors\"\n\t\"math/rand\"\n\t\"regexp\"\n\t\"testing\"\n\t\"time\"\n\n\t\"g"
  },
  {
    "path": "pkg/db/bolt/reqlog.go",
    "chars": 5201,
    "preview": "package bolt\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/gob\"\n\t\"errors\"\n\t\"fmt\"\n\n\t\"github.com/oklog/ulid\"\n\tbolt \"go.etcd.io/"
  },
  {
    "path": "pkg/db/bolt/reqlog_test.go",
    "chars": 3370,
    "preview": "package bolt_test\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/google/go-cmp/c"
  },
  {
    "path": "pkg/db/bolt/sender.go",
    "chars": 4345,
    "preview": "package bolt\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/gob\"\n\t\"errors\"\n\t\"fmt\"\n\n\t\"github.com/oklog/ulid\"\n\tbolt \"go.etcd.io/"
  },
  {
    "path": "pkg/db/bolt/sender_test.go",
    "chars": 5915,
    "preview": "package bolt_test\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/google/go-cmp/c"
  },
  {
    "path": "pkg/filter/ast.go",
    "chars": 1850,
    "preview": "package filter\n\nimport (\n\t\"encoding/gob\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"strings\"\n)\n\ntype Expression interface {\n\tString() string"
  },
  {
    "path": "pkg/filter/ast_test.go",
    "chars": 6237,
    "preview": "package filter_test\n\nimport (\n\t\"regexp\"\n\t\"testing\"\n\n\t\"github.com/dstotijn/hetty/pkg/filter\"\n)\n\nfunc TestExpressionString"
  },
  {
    "path": "pkg/filter/http.go",
    "chars": 2004,
    "preview": "package filter\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"net/http\"\n)\n\nfunc MatchHTTPHeaders(op TokenType, expr Expression, headers ht"
  },
  {
    "path": "pkg/filter/lexer.go",
    "chars": 4150,
    "preview": "package filter\n\nimport (\n\t\"fmt\"\n\t\"unicode\"\n\t\"unicode/utf8\"\n)\n\ntype TokenType int\n\ntype Token struct {\n\tType    TokenType"
  },
  {
    "path": "pkg/filter/lexer_test.go",
    "chars": 1731,
    "preview": "package filter\n\nimport \"testing\"\n\nfunc TestNextToken(t *testing.T) {\n\tt.Parallel()\n\n\ttests := []struct {\n\t\tname     stri"
  },
  {
    "path": "pkg/filter/parser.go",
    "chars": 4873,
    "preview": "package filter\n\nimport (\n\t\"fmt\"\n\t\"regexp\"\n)\n\ntype precedence int\n\nconst (\n\t_ precedence = iota\n\tprecLowest\n\tprecAnd\n\tpre"
  },
  {
    "path": "pkg/filter/parser_test.go",
    "chars": 6536,
    "preview": "package filter\n\nimport (\n\t\"errors\"\n\t\"reflect\"\n\t\"regexp\"\n\t\"testing\"\n)\n\nfunc TestParseQuery(t *testing.T) {\n\tt.Parallel()\n"
  },
  {
    "path": "pkg/log/log.go",
    "chars": 2380,
    "preview": "package log\n\nimport (\n\t\"fmt\"\n\t\"time\"\n\n\t\"go.uber.org/zap\"\n\t\"go.uber.org/zap/zapcore\"\n)\n\ntype Logger interface {\n\tDebugw(m"
  },
  {
    "path": "pkg/proj/proj.go",
    "chars": 7829,
    "preview": "package proj\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"math/rand\"\n\t\"regexp\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/oklog/ulid\"\n\n\t\"g"
  },
  {
    "path": "pkg/proj/repo.go",
    "chars": 342,
    "preview": "package proj\n\nimport (\n\t\"context\"\n\n\t\"github.com/oklog/ulid\"\n)\n\ntype Repository interface {\n\tFindProjectByID(ctx context."
  },
  {
    "path": "pkg/proxy/cert.go",
    "chars": 7333,
    "preview": "package proxy\n\nimport (\n\t\"bytes\"\n\t\"crypto\"\n\t\"crypto/rand\"\n\t\"crypto/rsa\"\n\t\"crypto/sha1\"\n\t\"crypto/tls\"\n\t\"crypto/x509\"\n\t\"cr"
  },
  {
    "path": "pkg/proxy/gzip.go",
    "chars": 708,
    "preview": "package proxy\n\nimport (\n\t\"bytes\"\n\t\"compress/gzip\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n)\n\nfunc gunzipResponseBody(res *http.Response"
  },
  {
    "path": "pkg/proxy/intercept/filter.go",
    "chars": 10954,
    "preview": "package intercept\n\nimport (\n\t\"bytes\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"io/ioutil\"\n\t\"net/http\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com"
  },
  {
    "path": "pkg/proxy/intercept/intercept.go",
    "chars": 11893,
    "preview": "package intercept\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"sort\"\n\t\"sync\"\n\n\t\"github.com/oklog/ulid\"\n\n\t\"github."
  },
  {
    "path": "pkg/proxy/intercept/intercept_test.go",
    "chars": 6675,
    "preview": "package intercept_test\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"math/rand\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"sync\"\n\t\"testing\"\n\t"
  },
  {
    "path": "pkg/proxy/intercept/settings.go",
    "chars": 209,
    "preview": "package intercept\n\nimport \"github.com/dstotijn/hetty/pkg/filter\"\n\ntype Settings struct {\n\tRequestsEnabled  bool\n\tRespons"
  },
  {
    "path": "pkg/proxy/modify.go",
    "chars": 816,
    "preview": "package proxy\n\nimport \"net/http\"\n\nvar (\n\tnopReqModifier = func(req *http.Request) {}\n\tnopResModifier = func(res *http.Re"
  },
  {
    "path": "pkg/proxy/net.go",
    "chars": 802,
    "preview": "package proxy\n\nimport (\n\t\"errors\"\n\t\"net\"\n)\n\nvar ErrAlreadyAccepted = errors.New(\"listener already accepted\")\n\n// OnceLis"
  },
  {
    "path": "pkg/proxy/proxy.go",
    "chars": 5977,
    "preview": "package proxy\n\nimport (\n\t\"context\"\n\t\"crypto\"\n\t\"crypto/tls\"\n\t\"crypto/x509\"\n\t\"errors\"\n\t\"fmt\"\n\t\"math/rand\"\n\t\"net\"\n\t\"net/htt"
  },
  {
    "path": "pkg/reqlog/repo.go",
    "chars": 553,
    "preview": "package reqlog\n\nimport (\n\t\"context\"\n\n\t\"github.com/oklog/ulid\"\n\n\t\"github.com/dstotijn/hetty/pkg/scope\"\n)\n\ntype Repository"
  },
  {
    "path": "pkg/reqlog/reqlog.go",
    "chars": 6222,
    "preview": "package reqlog\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"io/ioutil\"\n\t\"net/http\"\n\t\"net/url\"\n\n\t\"github.com/ok"
  },
  {
    "path": "pkg/reqlog/reqlog_test.go",
    "chars": 4224,
    "preview": "package reqlog_test\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"math/rand\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"strings\"\n\t\"testing\"\n\t\"tim"
  },
  {
    "path": "pkg/reqlog/search.go",
    "chars": 6849,
    "preview": "package reqlog\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/oklog/ulid\"\n\n\t\"github.com/dstotijn/hetty/p"
  },
  {
    "path": "pkg/reqlog/search_test.go",
    "chars": 4655,
    "preview": "package reqlog_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/dstotijn/hetty/pkg/filter\"\n\t\"github.com/dstotijn/hetty/pkg/reqlog"
  },
  {
    "path": "pkg/scope/scope.go",
    "chars": 3009,
    "preview": "package scope\n\nimport (\n\t\"bytes\"\n\t\"encoding/gob\"\n\t\"net/http\"\n\t\"regexp\"\n\t\"sync\"\n)\n\ntype Scope struct {\n\trules []Rule\n\tmu "
  },
  {
    "path": "pkg/sender/repo.go",
    "chars": 458,
    "preview": "package sender\n\nimport (\n\t\"context\"\n\n\t\"github.com/oklog/ulid\"\n\n\t\"github.com/dstotijn/hetty/pkg/scope\"\n)\n\ntype Repository"
  },
  {
    "path": "pkg/sender/search.go",
    "chars": 6408,
    "preview": "package sender\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/oklog/ulid\"\n\n\t\"github.com/dstotijn/hetty/pkg/filter\"\n"
  },
  {
    "path": "pkg/sender/search_test.go",
    "chars": 4627,
    "preview": "package sender_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/dstotijn/hetty/pkg/filter\"\n\t\"github.com/dstotijn/hetty/pkg/reqlog"
  },
  {
    "path": "pkg/sender/sender.go",
    "chars": 5761,
    "preview": "package sender\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"math/rand\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"time\"\n\n\t\"github.com/"
  },
  {
    "path": "pkg/sender/sender_test.go",
    "chars": 7439,
    "preview": "package sender_test\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"math/rand\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"net/url\"\n\t\"tes"
  },
  {
    "path": "pkg/sender/transport.go",
    "chars": 1367,
    "preview": "package sender\n\nimport (\n\t\"crypto/tls\"\n\t\"net\"\n\t\"net/http\"\n\t\"time\"\n)\n\ntype HTTPTransport struct{}\n\ntype protoCtxKey struc"
  },
  {
    "path": "tools.go",
    "chars": 93,
    "preview": "//go:build tools\n// +build tools\n\npackage tools\n\nimport (\n\t_ \"github.com/99designs/gqlgen\"\n)\n"
  }
]

About this extraction

This page contains the full source code of the dstotijn/hetty GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 161 files (688.4 KB), approximately 198.7k tokens, and a symbol index with 1051 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!