377 lines
13 KiB
Markdown
377 lines
13 KiB
Markdown
# CLAUDE.md
|
|
|
|
This file provides guidance to Claude Code (claude.ai/code) when working with
|
|
code in this repository.
|
|
|
|
## Project Overview
|
|
|
|
Xget is a high-performance, Cloudflare Workers-based acceleration engine for
|
|
developer resources. It provides unified acceleration for code repositories
|
|
(GitHub, GitLab, etc.), package registries (npm, PyPI, Maven, etc.), container
|
|
registries (Docker Hub, GHCR, etc.), and AI inference APIs (OpenAI, Anthropic,
|
|
etc.).
|
|
|
|
The project operates as a reverse proxy that transforms incoming requests to
|
|
match various platform APIs while adding security headers, caching, retry logic,
|
|
and performance monitoring.
|
|
|
|
## Development Commands
|
|
|
|
### Core Commands
|
|
|
|
```bash
|
|
# Start development server (Cloudflare Workers local environment)
|
|
npm run dev # Runs on http://localhost:8787
|
|
|
|
# Deploy to Cloudflare Workers production
|
|
npm run deploy
|
|
|
|
# Build and run tests
|
|
npm run test # Run tests in watch mode
|
|
npm run test:run # Run tests once
|
|
npm run test:coverage # Generate coverage report
|
|
npm run test:ui # Open Vitest UI
|
|
|
|
# Code quality
|
|
npm run lint # Check code quality
|
|
npm run lint:fix # Fix linting issues
|
|
npm run format # Format code with Prettier
|
|
npm run format:check # Check formatting without changes
|
|
npm run type-check # TypeScript type checking (no emit)
|
|
npm run commitlint # Validate the latest commit message
|
|
```
|
|
|
|
## Commit Messages
|
|
|
|
- Use [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) for
|
|
every commit
|
|
- Preferred format: `type(scope): description`
|
|
- Common types: `feat`, `fix`, `docs`, `refactor`, `perf`, `test`, `chore`
|
|
- The repository installs a `commit-msg` hook via `npm install`; do not bypass
|
|
it unless explicitly required
|
|
|
|
## Pre-Commit Requirements
|
|
|
|
- Before every commit, run the local CI-equivalent checks from
|
|
`.github/workflows/ci.yml`
|
|
- Required commands: `npm run lint`, `npm run format:check`, `npm run test:run`,
|
|
and `npm run type-check`
|
|
- If any required check fails, do not commit until the failure is resolved
|
|
- Apply this rule to every commit, including documentation-only changes, unless
|
|
the user explicitly asks for a different workflow
|
|
|
|
### Testing Workflow
|
|
|
|
- Tests use Vitest with `@cloudflare/vitest-pool-workers` for Workers-specific
|
|
testing
|
|
- Run `npm run test:run` before committing to ensure all tests pass
|
|
- Coverage reports are generated in `coverage/` directory
|
|
|
|
## Architecture
|
|
|
|
### Request Flow
|
|
|
|
1. **Entry Point**: `src/index.js` - Exports default Worker with `fetch()`
|
|
handler
|
|
2. **Validation**: `src/utils/validation.js` - Validates HTTP methods, path
|
|
length, detects protocol types
|
|
3. **Platform Detection**: URL path is parsed to identify platform (e.g., `/gh/`
|
|
→ GitHub)
|
|
4. **Path Transformation**:
|
|
`src/routing/platform-transformers.js#transformPath()` converts request paths
|
|
to upstream URLs
|
|
5. **Protocol Handling**: Different handlers for Git, Docker, AI inference
|
|
requests
|
|
6. **Upstream Fetch**: Request forwarded with appropriate headers and retry
|
|
logic
|
|
7. **Response Processing**: URL rewriting for certain platforms (npm, PyPI),
|
|
cache storage
|
|
8. **Security Headers**: Added via `src/utils/security.js` before returning to
|
|
client
|
|
|
|
### Key Components
|
|
|
|
#### Configuration (`src/config/`)
|
|
|
|
- **`index.js`**: Runtime configuration with environment variable overrides
|
|
- `TIMEOUT_SECONDS`: Request timeout (default: 30s)
|
|
- `MAX_RETRIES`: Retry attempts (default: 3)
|
|
- `CACHE_DURATION`: Fallback mutable cache TTL (default: 300s = 5 minutes)
|
|
- `SECURITY.ALLOWED_METHODS`: HTTP methods (default: GET, HEAD)
|
|
|
|
- **`platform-catalog.js`**: Platform base URL definitions
|
|
- `PLATFORM_CATALOG`: Object mapping platform keys to base URLs
|
|
|
|
- **`routing/platform-index.js`**: Pre-sorted keys for efficient matching
|
|
- `SORTED_PLATFORMS`: Longest-prefix-first platform matching order
|
|
|
|
- **`routing/platform-transformers.js`**: Platform-specific path rewriting
|
|
- `transformPath()`: Converts request paths to platform-specific URLs
|
|
- Special handling for crates.io (adds `/api/v1/crates` prefix) and Jenkins
|
|
(adds `/current/` prefix)
|
|
|
|
#### Protocol Handlers (`src/protocols/`)
|
|
|
|
- **`git.js`**: Git protocol detection and header configuration
|
|
- Detects Git operations via User-Agent, endpoints (`/info/refs`,
|
|
`/git-upload-pack`)
|
|
- Handles Git LFS via `Accept: application/vnd.git-lfs+json`
|
|
|
|
- **`docker.js`**: Container registry protocol (OCI/Docker)
|
|
- Parses WWW-Authenticate headers for token authentication
|
|
- Handles Docker registry v2 API authentication flow
|
|
- Special redirect handling to prevent leaking auth tokens to blob storage
|
|
|
|
- **`ai.js`**: AI inference API detection and header forwarding
|
|
- Detects requests to `/ip/*` platforms
|
|
- Preserves all headers for AI API compatibility
|
|
|
|
#### Utilities (`src/utils/`)
|
|
|
|
- **`validation.js`**: Request validation logic
|
|
- `isDockerRequest()`: Detects Docker/OCI operations
|
|
- `validateRequest()`: Enforces security policies
|
|
|
|
- **`security.js`**: Security headers and error responses
|
|
- Adds HSTS, X-Frame-Options, CSP, X-XSS-Protection
|
|
- `createErrorResponse()`: Generates standardized error responses
|
|
|
|
- **`performance.js`**: Performance monitoring
|
|
- `PerformanceMonitor`: Tracks request timing
|
|
- Adds `X-Performance-Metrics` header to responses
|
|
|
|
### Caching Strategy
|
|
|
|
- Uses Cloudflare Cache API for GET requests (200 OK only)
|
|
- Fallback mutable cache TTL controlled by `CACHE_DURATION` config
|
|
- Skips cache for: Git operations, Docker operations, AI inference requests
|
|
- Range requests: First checks for range-specific cache, falls back to full
|
|
content cache
|
|
|
|
### Special Platform Handling
|
|
|
|
#### npm
|
|
|
|
- Rewrites `https://registry.npmjs.org/` URLs in JSON responses to point to Xget
|
|
instance
|
|
|
|
#### PyPI
|
|
|
|
- Rewrites `https://files.pythonhosted.org` URLs in HTML responses to point to
|
|
Xget instance
|
|
- Uses separate `pypi-files` platform for file downloads
|
|
|
|
#### crates.io
|
|
|
|
- Adds `/api/v1/crates` prefix to all API requests
|
|
- Handles search endpoint (`/?q=`) specially
|
|
|
|
#### Jenkins
|
|
|
|
- Adds `/current/` prefix to update center paths
|
|
- Preserves `/experimental/` and `/download/` paths as-is
|
|
|
|
#### Docker Registries
|
|
|
|
- Handles authentication via token service
|
|
- Uses manual redirect mode to strip Authorization headers before S3 redirects
|
|
- Auto-retries with public token on 401 responses
|
|
|
|
## Code Structure Conventions
|
|
|
|
### File Organization
|
|
|
|
```
|
|
src/
|
|
├── index.js # Main Worker entry point
|
|
├── app/
|
|
│ ├── handle-request.js # Shared request pipeline
|
|
│ └── request-context.js # Protocol-aware request classification
|
|
├── config/
|
|
│ ├── index.js # Runtime configuration
|
|
│ ├── platform-catalog.js # Platform base URLs
|
|
│ └── platforms.js # Compatibility exports
|
|
├── protocols/
|
|
│ ├── git.js # Git protocol handler
|
|
│ ├── docker.js # Docker/OCI handler
|
|
│ └── ai.js # AI inference handler
|
|
├── response/
|
|
│ └── finalize-response.js # Response shaping and cache writes
|
|
├── routing/
|
|
│ ├── platform-index.js # Platform matching order
|
|
│ ├── platform-transformers.js
|
|
│ └── resolve-target.js # Upstream target resolution
|
|
├── upstream/
|
|
│ ├── cache.js # Cache read helpers
|
|
│ └── fetch-upstream.js # Upstream transport and retries
|
|
└── utils/
|
|
├── validation.js # Request validation
|
|
├── security.js # Security utilities
|
|
└── performance.js # Performance monitoring
|
|
|
|
test/
|
|
├── features/ # Feature tests
|
|
├── platforms/ # Platform-specific tests
|
|
├── unit/ # Unit tests
|
|
├── index.test.js # Core Worker tests
|
|
└── integration.test.js # Integration tests
|
|
```
|
|
|
|
### Important Patterns
|
|
|
|
#### Protocol Detection Order
|
|
|
|
1. Check if Docker request (via `isDockerRequest()`)
|
|
2. Check if Git request (via `isGitRequest()`)
|
|
3. Check if Git LFS request (via `isGitLFSRequest()`)
|
|
4. Check if AI request (via `isAIInferenceRequest()`)
|
|
5. Default to standard file download
|
|
|
|
#### Adding a New Platform
|
|
|
|
1. Add platform entry to `PLATFORM_CATALOG` in `src/config/platform-catalog.js`
|
|
2. If special path transformation needed, add a transformer in
|
|
`src/routing/platform-transformers.js`
|
|
3. Add platform tests in `test/platforms/`
|
|
4. Update README.md with platform documentation
|
|
|
|
#### Retry Logic
|
|
|
|
- Retries up to `MAX_RETRIES` times with linear backoff
|
|
- Delay: `RETRY_DELAY_MS * attempts` (default: 1000ms, 2000ms, 3000ms)
|
|
- Retries on: Network errors, timeouts, 5xx errors
|
|
- Does NOT retry: 4xx errors (except Docker 401 which has special handling)
|
|
|
|
#### Error Handling
|
|
|
|
- All errors caught at top level in `handleRequest()`
|
|
- Errors converted to JSON responses via `createErrorResponse()`
|
|
- Performance metrics still added even on error paths
|
|
|
|
## Testing Guidelines
|
|
|
|
### Test Structure
|
|
|
|
- **Unit tests** (`test/unit/`): Test individual functions in isolation
|
|
- **Feature tests** (`test/features/`): Test specific features (auth, caching,
|
|
Git, performance)
|
|
- **Platform tests** (`test/platforms/`): Test platform-specific transformations
|
|
- **Integration tests** (`test/integration.test.js`): End-to-end request flows
|
|
|
|
### Running Specific Tests
|
|
|
|
```bash
|
|
# Run specific test file
|
|
npm run test:run test/unit/platforms.test.js
|
|
|
|
# Run tests matching pattern
|
|
npm run test:run -- --testNamePattern "Docker"
|
|
|
|
# Run with coverage
|
|
npm run test:coverage
|
|
```
|
|
|
|
### Common Test Patterns
|
|
|
|
```javascript
|
|
// Mock request creation
|
|
const request = new Request('http://localhost/gh/microsoft/vscode', {
|
|
method: 'GET',
|
|
headers: { 'User-Agent': 'git/2.34.1' }
|
|
});
|
|
|
|
// Mock environment
|
|
const env = {};
|
|
const ctx = { waitUntil: () => {} };
|
|
|
|
// Test the worker
|
|
const response = await worker.fetch(request, env, ctx);
|
|
expect(response.status).toBe(200);
|
|
```
|
|
|
|
## Deployment
|
|
|
|
### Cloudflare Workers
|
|
|
|
- Primary deployment target
|
|
- Uses GitHub Actions for CI/CD (`.github/workflows/workers.yml`)
|
|
- Requires `CLOUDFLARE_API_TOKEN` and `CLOUDFLARE_ACCOUNT_ID` secrets
|
|
|
|
### Cloudflare Pages
|
|
|
|
- Alternative deployment via adapter in `adapters/pages/`
|
|
- Auto-synced from `main` branch to `pages` branch
|
|
- Uses separate workflow (`.github/workflows/pages-cf.yml`)
|
|
|
|
### Other Platforms
|
|
|
|
- **Vercel/Netlify**: Uses Functions adapter in `adapters/functions/`
|
|
- **Deno Deploy**: Uses Functions adapter (compatible format)
|
|
- **Docker**: Multi-stage build using `workerd` runtime
|
|
|
|
### Environment Variables
|
|
|
|
Configure in Cloudflare Workers dashboard or via `wrangler.toml`:
|
|
|
|
- `TIMEOUT_SECONDS`: Override default timeout
|
|
- `MAX_RETRIES`: Override retry count
|
|
- `CACHE_DURATION`: Override fallback mutable cache TTL
|
|
- `ALLOWED_METHODS`: Override allowed HTTP methods (comma-separated)
|
|
- `ALLOWED_ORIGINS`: Override CORS origins (comma-separated)
|
|
|
|
## Important Notes
|
|
|
|
### Security Considerations
|
|
|
|
- Never log or expose Authorization headers
|
|
- Docker authentication tokens are stripped before S3 redirects
|
|
- All responses include security headers (HSTS, CSP, X-Frame-Options, etc.)
|
|
- Path length limited to prevent URL-based attacks (default: 2048 chars)
|
|
|
|
### Performance Optimization
|
|
|
|
- Use `ctx.waitUntil()` for cache writes to avoid blocking response
|
|
- Range requests leverage cache when possible
|
|
- Cloudflare edge caching (`cf` fetch options) for non-protocol requests
|
|
- HTTP/3 enabled for supported clients
|
|
|
|
### Git/Docker/AI Requests
|
|
|
|
- Skip normal caching mechanisms
|
|
- Allow POST/PUT/PATCH methods
|
|
- Preserve all upstream headers
|
|
- No performance headers added (to maintain protocol compatibility)
|
|
|
|
### URL Rewriting
|
|
|
|
- Only enabled for npm and PyPI platforms
|
|
- Rewrites responses to point to Xget instance instead of upstream
|
|
- Required for package managers to download dependencies through Xget
|
|
|
|
## Common Tasks
|
|
|
|
### Adding a New Platform
|
|
|
|
1. Add to `PLATFORM_CATALOG` in `src/config/platform-catalog.js`
|
|
2. If special transformation needed, update
|
|
`src/routing/platform-transformers.js`
|
|
3. Add test in `test/platforms/`
|
|
4. Update README.md documentation
|
|
5. Test locally with `npm run dev`
|
|
|
|
### Debugging Requests
|
|
|
|
1. Use `npm run dev` to start local server
|
|
2. Add `console.log()` statements in `src/app/handle-request.js` or the relevant
|
|
extracted pipeline module
|
|
3. Check Wrangler dev server output
|
|
4. Inspect `X-Performance-Metrics` header in responses
|
|
|
|
### Fixing Test Failures
|
|
|
|
1. Run specific failing test: `npm run test:run test/path/to/test.js`
|
|
2. Check mock setup matches actual request pattern
|
|
3. Verify platform configuration in `src/config/platform-catalog.js` and
|
|
`src/routing/platform-transformers.js`
|
|
4. Run all tests before committing: `npm run test:run`
|