Metadata-Version: 2.1
Name: api-ghost-hunter
Version: 0.1.0
Summary: Static-analysis CLI that detects mismatches between frontend API calls and backend endpoints.
Author: API Ghost Hunter Contributors
License: MIT
Project-URL: Homepage, https://github.com/api-ghost-hunter/api-ghost-hunter
Project-URL: Repository, https://github.com/api-ghost-hunter/api-ghost-hunter
Project-URL: Issues, https://github.com/api-ghost-hunter/api-ghost-hunter/issues
Keywords: api,static-analysis,frontend,backend,cli,ghost,hunter
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Quality Assurance
Classifier: Topic :: Software Development :: Testing
Requires-Python: >=3.9
Description-Content-Type: text/markdown
Requires-Dist: typer>=0.9.0
Requires-Dist: rich>=13.0.0
Requires-Dist: pydantic>=2.0.0
Requires-Dist: pyyaml>=6.0
Provides-Extra: dev
Requires-Dist: pytest>=7.0.0; extra == "dev"
Requires-Dist: ruff>=0.4.0; extra == "dev"

# 👻 API Ghost Hunter

[![Python Support](https://img.shields.io/badge/python-3.9%20%7C%203.10%20%7C%203.11%20%7C%203.12%20%7C%203.13-blue.svg)](https://github.com/api-ghost-hunter/api-ghost-hunter)
[![CI status](https://img.shields.io/github/actions/workflow/status/api-ghost-hunter/api-ghost-hunter/test.yml?branch=main)](https://github.com/api-ghost-hunter/api-ghost-hunter/actions)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

A static-analysis CLI tool that scans full-stack codebases, detects API calls made by the frontend, detects API endpoints exposed by the backend, compares them, and identifies broken paths, potentially unused endpoints, and method mismatches. Supports both local directories and remote GitHub repositories.

---

## The Problem

In modern full-stack web applications, frontends and backends evolve at different speeds. Over time, APIs get renamed, endpoints are deleted, and query/path parameter requirements shift. This leaves:
- **Ghost Calls**: Frontend code calling endpoints that no longer exist, causing `404 Not Found` errors in production.
- **Ghost Endpoints**: Backend controllers exposing dead code that is no longer consumed by the frontend, adding maintenance overhead.

**API Ghost Hunter** solves this problem by statically analyzing your repository without requiring a running server, dynamic agents, or complicated integration test suites.

---

## Key Features

- **Static Analysis**: Scans source code directly. Safe, fast, and does not require running your application or database.
- **Remote Repository Scanning**: Directly scan remote GitHub, GitLab, or Bitbucket repositories by passing the Git URL.
- **Frontend Support**: Automatically detects JS/TS `fetch()` calls, direct and config-style `axios` requests, `axios.create()` instances with custom `baseURL` resolutions, **Angular HttpClient**, and **jQuery AJAX** shorthand/config calls.
- **Backend Support**: Full detection of Spring Boot, Express.js, Flask, FastAPI, Django & DRF, NestJS, **Go** (Gin, Echo, Chi, net/http), **Ruby on Rails**, and **OpenAPI/Swagger specs**.
- **Dynamic Route Matching**: Correctly handles and matches path parameters such as `/api/users/123` with backend mappings like `/api/users/{id}`.
- **Method Mismatch Detection**: Reports when paths match but HTTP methods differ (e.g., frontend requests GET but backend expects POST).
- **Intelligent Recommendations**: Suggests similar matching endpoints using deterministic similarity algorithms (difflib, segment edit distance) with a confidence score.
- **Environment Variable Resolution**: Reads `.env`, `.env.local`, and `.env.development` files to resolve runtime URL strings used in frontends.
- **CI/CD Integration**: Supports custom exit codes (`--fail-on-broken`), ignore files, JSON/SARIF reporting formats, and summary-only output.

---

## Installation

You can install API Ghost Hunter from source or via pip (once published):

```bash
# Clone the repository
git clone https://github.com/api-ghost-hunter/api-ghost-hunter.git
cd api-ghost-hunter

# Install in editable mode
pip install -e .
```

---

## Quick-Start Example

Scan your local workspace from the command line:

```bash
api-ghost-hunter scan .
```

Scan a remote GitHub repository directly:

```bash
api-ghost-hunter scan https://github.com/owner/fullstack-app
```

Scan separate remote frontend and backend repositories:

```bash
api-ghost-hunter scan . --frontend https://github.com/owner/frontend --backend https://github.com/owner/backend
```

Generate a SARIF report file for GitHub Code Scanning integration:

```bash
api-ghost-hunter scan . --format sarif -o results.sarif
```

Fail the CI build if there are broken calls with minimal output:

```bash
api-ghost-hunter scan . --quiet --fail-on-broken
```

Create a template configuration file:

```bash
api-ghost-hunter init
```

Display the complete interactive guide and tech reference:

```bash
api-ghost-hunter guide
```

---

## Example Terminal Output

```text
╭──────────────────────────────────────────────────────────────────────────────╮
│                                                                              │
│                                                                              │
│   █▀▀█ █▀▀█ ▀█▀   █▀▀█ █  █ █▀▀█ █▀▀▀ ▀▀█▀▀   █  █ █  █ █▀▀█ ▀▀█▀▀ █▀▀ █▀▀█  │
│   █▄▄█ █▄▄█  █    █ ▄▄ █▀▀█ █  █ ▀▀▀█   █     █▀▀█ █  █ █  █   █   █▀▀ █▄▄▀  │
│   ▀  ▀ ▀    ▄█▄   ▀▄▄█ ▀  ▀ ▀  ▀ █▄▄█   ▀     ▀  ▀ ▀▀▀▀ ▀  ▀   ▀   ▀▀▀ ▀ ▀▀  │
│                                                                              │
│    » Static API Contract & Drift Analyzer «  v0.1.0                          │
│                                                                              │
╰──────────────────────────────────────────────────────────────────────────────╯

╭─ 📊 Scan Metrics ────────────────────────────────────────────────────────────╮
│   Frontend API Calls Scanned      13                                         │
│   Backend Endpoints Scanned       64                                         │
│   API Contract Matches            10                                         │
│   Broken Calls (Ghost APIs)        2                                         │
│   HTTP Method Mismatches           0                                         │
│   Potentially Unused Endpoints    55                                         │
│   Unresolved Dynamic Calls         1                                         │
╰──────────────────────────────────────────────────────────────────────────────╯

🔴 GHOST APIS DETECTED (BROKEN CONTRACTS)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
╭──────────────────────────────────────────────────────────────────────────────╮
│ CRITICAL: Frontend tries to call non-existent endpoint:                      │
│   POST /api/posts                                                            │
│                                                                              │
│   Location:  frontend/src/api.js:17 (axios framework)                        │
│       » POST /api/users (63%)                                                │
│       » POST /api/users (63%)                                                │
│       » POST /api/users (63%)                                                │
╰──────────────────────────────────────────────────────────────────────────────╯
╭──────────────────────────────────────────────────────────────────────────────╮
│ CRITICAL: Frontend tries to call non-existent endpoint:                      │
│   GET /api/orders                                                            │
│                                                                              │
│   Location:  frontend/src/api.js:40 (axios framework)                        │
│       » GET /api/users (66%)                                                 │
│       » GET /api/users (66%)                                                 │
│       » GET /api/users (66%)                                                 │
╰──────────────────────────────────────────────────────────────────────────────╯
```

---

## Detailed Technical Architecture & Logic

### 1. Static Parsing Engine

#### A. Frontend API Call Detection
The frontend parser scans JS/TS/TSX files for API calls. Rather than using simplistic global regexes, it uses a multi-stage parser:
1. **Comment Stripping**: The parser strips block (`/* ... */`) and line (`// ...`) comments while replacing characters with whitespace/newlines. This preserves the exact code positions and line numbers for warnings and errors.
2. **Fetch Extraction**: Resolves calls to the standard `fetch()` API. If a method option is not explicitly found, it defaults to `GET`.
3. **Axios Extraction**: Resolves direct axios methods (`axios.get`, `axios.post`, etc.), standard axios configuration parameters (`axios({ method: "...", url: "..." })`), and custom client instances initialized via `axios.create({ baseURL: "/api" })`. The parser tracks multiple instances and automatically prepends their configured `baseURL` values to relative target endpoints.
4. **Angular HttpClient**: Extracts constructor-injected `HttpClient` calls (e.g. `this.http.get<Item[]>('/api/items')` or `this.http.request('POST', ...)`) in TypeScript components.
5. **jQuery AJAX**: Resolves shorthand jQuery calls (`$.get`, `$.post`, `$.getJSON`) and config objects (`$.ajax({ url: '/api', method: 'PUT' })`).
6. **Template Literals**: Translates template string placeholders (e.g. `` `/api/users/${userId}` ``) into generic tokens (e.g. `/api/users/{param}`) for route matching.
7. **Environment Variables**: Resolves `process.env.*` and `import.meta.env.*` references by matching them with keys found in local `.env`, `.env.local`, and `.env.development` files.
8. **Unresolved Variable Detection**: If the endpoint URL is composed of an unresolvable variable or custom function call (e.g., `fetch(apiUrl)`), it logs the expression as `UNRESOLVED` to prevent false positive broken alerts.

#### B. Backend Endpoint Detection
The backend parser extracts exposed controller mappings:
1. **Spring Boot (Java/Kotlin)**: Scans `@RequestMapping("/prefix")` annotations declared at the controller class level.
2. **Express.js (Node.js)**: Resolves router instances, `app.get/post`, chaining, and mount paths using `.use()`.
3. **Flask (Python)**: Parses `@app.route()`, `methods=` arrays, Blueprint routing, and `<converter>` variables.
4. **FastAPI (Python)**: Extracts path parameters, async/sync routes, and `APIRouter` sub-routers.
5. **Django (Python)**: Resolves urlpatterns (`path()`, `re_path()`), DRF Routers (`DefaultRouter`, `SimpleRouter`), ViewSets, and `@api_view` decorated functions.
6. **NestJS (TypeScript)**: Detects controller decorators, HTTP method mappings, and router prefix structures.
7. **Go (Go)**: Resolves Gin (`r.GET`), Echo (`e.POST`), Chi (`r.Get`), net/http (`http.HandleFunc`), and route groups.
8. **Ruby on Rails (Ruby)**: Parses `routes.rb` for standard verbs, resource macros (`resources :users`), scopes, namespaces, and root paths.
9. **OpenAPI / Swagger Specs**: Parses API schemas (`openapi.yaml/json`, `swagger.yaml/json`), extracting URLs, basePath configuration, servers block, and HTTP methods.

#### C. Smart Parser Selection
To ensure fast execution in large codebases, the scanner does not run all backend parsers on every file. It matches file extensions to select relevant parsers (e.g. `.py` files only invoke Django/Flask/FastAPI parsers, `.go` only invokes Go parser, etc.), significantly reducing processing time.

---

### 2. Route Normalization

Before matching, paths are normalized to guarantee comparison consistency:
- **Query Stripping**: Removes query parameters (e.g. `/api/users?page=1` becomes `/api/users`).
- **Hash/Fragment Stripping**: Removes hash segments (e.g. `/api/users#profile` becomes `/api/users`).
- **Slash Consolidation**: Collapses consecutive slashes (e.g. `/api//users/` becomes `/api/users`).
- **Trailing Slash Removal**: Strips trailing slashes (e.g. `/api/users/` becomes `/api/users`).
- **Spring Parameter Regex Normalization**: Cleans up path parameter validation regexes (e.g., `/api/users/{id:\d+}` becomes `/api/users/{id}`).
- **Case Insensitivity**: Converts paths to lowercase.

---

### 3. Matching & Similarity Engine

The engine resolves matching in five sequential passes to prevent false reports:

| Pass | Match Category | Details |
|---|---|---|
| **1** | **Exact Match** | Matches exact normalized path and HTTP method (e.g. frontend `GET /api/users` vs backend `GET /api/users`). |
| **2** | **Dynamic Route Match** | Matches path parameters and dynamic variables (e.g. frontend `/api/users/123` or `/api/users/{param}` vs backend `/api/users/{id}`). |
| **3** | **Method Mismatch** | Matches the endpoint path, but the HTTP method differs (e.g., frontend sends `GET /api/orders` but backend accepts `POST /api/orders`). |
| **4** | **Similar suggestions** | If there is no match, computes similarity scores between the broken path and exposed backend endpoints using token segment comparison combined with edit-distance ratios. |
| **5** | **Potentially Unused** | Any backend endpoints that remain unmatched by any frontend call are flagged as "Potentially Unused". |

---

## Supported Technologies

| Layer | Library / Framework | Support Features |
|---|---|---|
| **Frontend** | JS/TS `fetch()` | Direct URLs, Multi-line options objects, Method extraction, Template literals |
| **Frontend** | Axios (`axios`) | Direct calls, Config-style calls, `axios.create()` instances, `baseURL` resolutions |
| **Frontend** | Angular `HttpClient` | `http.get<T>()`, `http.post()`, etc., `http.request()`, constructor injection resolution |
| **Frontend** | jQuery AJAX | `$.get()`, `$.post()`, `$.getJSON()`, `$.ajax()` configuration parameters |
| **Backend** | Spring Boot | `@RequestMapping`, `@GetMapping`, `@PostMapping`, etc., class-level + method-level path combination, array paths |
| **Backend** | Express.js (Node.js) | `app.get()`, `app.post()`, `app.put()`, `app.patch()`, `app.delete()`, `app.all()`, `app.route()`, `express.Router()`, `app.use()` mounting, `:param` path params |
| **Backend** | Flask (Python) | `@app.route()`, `@app.get()`, `@app.post()`, methods array, converters, Blueprints |
| **Backend** | FastAPI (Python) | `@app.get()`, `@app.post()`, `@app.api_route()`, `APIRouter`, `{param}`, `{param:type}`, async routes |
| **Backend** | Django (Python) | `path()`, `re_path()`, default and simple DRF routers, DRF ViewSets, `@api_view` decorators |
| **Backend** | NestJS (TypeScript) | `@Controller()` with prefix, `@Get()`, `@Post()`, `@Put()`, `@Patch()`, `@Delete()`, `@All()`, `:param` path params |
| **Backend** | Go Router | Gin (`r.GET`), Echo (`e.POST`), Chi (`r.Get`), net/http (`http.HandleFunc`), group prefix resolution |
| **Backend** | Ruby on Rails | `get/post/put/delete`, `resources` macro with `only`/`except` filters, namespace, scope blocks |
| **Specs** | OpenAPI / Swagger | YAML & JSON format support, servers configuration blocks, basePath definitions |

---

## Configuration

You can configure options in a project-root configuration file called `ghosthunter.yaml`:

```yaml
frontend:
  paths:
    - frontend/src

backend:
  paths:
    - backend/src

ignore:
  - "/actuator/**"
  - "/api/internal/**"

exclude:
  - "**/*.test.ts"
  - "**/generated/**"
```

### Configuration Fields
- **frontend.paths**: A list of paths to look for frontend files in. Defaults to root scan directory if omitted.
- **backend.paths**: A list of paths to look for backend files in. Defaults to root scan directory if omitted.
- **ignore**: API URL path patterns (glob-style) to ignore from matching. If an API call or endpoint starts with or matches a prefix, it is skipped.
- **exclude**: File exclusion patterns (glob-style) to skip scanning (e.g. test files, mock databases).

CLI arguments take precedence over any settings specified in `ghosthunter.yaml`.

---

## CLI Reference

### `api-ghost-hunter scan`
```bash
api-ghost-hunter scan [DIRECTORY] [OPTIONS]
```

#### Arguments
- `DIRECTORY`: The root workspace directory or remote Git repository URL to scan. Defaults to `.`.

#### Options
- `--frontend`: Override frontend folder paths or remote Git URL.
- `--backend`: Override backend folder paths or remote Git URL.
- `--format`: Output format: `terminal` (polished panels), `json`, or `sarif`.
- `--output`, `-o`: File path to write the JSON/SARIF report to.
- `--quiet`, `-q`: Print only a one-line summary. Ideal for CI/CD usage.
- `--fail-on-broken`: If set, returns exit code `1` when any broken frontend call is detected.
- `--ignore`: Add API patterns to ignore during scan.
- `--verbose`: Show detailed debug logs and warnings.

### `api-ghost-hunter init`
```bash
api-ghost-hunter init [DIRECTORY] [OPTIONS]
```
Generates a starter `ghosthunter.yaml` configuration file.

### `api-ghost-hunter guide`
```bash
api-ghost-hunter guide
```
Displays complete user manual and framework documentation directly in the terminal.

#### Exit Codes
- `0`: Scan completed cleanly with no broken calls.
- `1`: Broken frontend calls (or method mismatches) were detected (only triggers if `--fail-on-broken` is enabled).
- `2`: Configuration, parsing, or command execution error.

---

## CI/CD Usage

### GitHub Actions (SARIF Integration)
Add this step to your GitHub Actions workflow file to run checks and upload results:

```yaml
- name: Run API Ghost Hunter Scan
  run: |
    pip install api-ghost-hunter
    api-ghost-hunter scan . --format sarif --output results.sarif

- name: Upload SARIF report
  uses: github/codeql-action/upload-sarif@v3
  with:
    sarif_file: results.sarif
```

---

## Contributing

Please read [CONTRIBUTING.md](CONTRIBUTING.md) for details on our code of conduct and the process for submitting pull requests.

---

## License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
