Skip to content

feat: add record and replay proxy for automatic fixture generation#62

Open
mvanhorn wants to merge 3 commits intovercel-labs:mainfrom
mvanhorn:feat/record-replay
Open

feat: add record and replay proxy for automatic fixture generation#62
mvanhorn wants to merge 3 commits intovercel-labs:mainfrom
mvanhorn:feat/record-replay

Conversation

@mvanhorn
Copy link
Copy Markdown
Contributor

@mvanhorn mvanhorn commented Apr 8, 2026

Summary

Add emulate record command that proxies requests to real APIs, records the traffic, and generates an emulate.config.yaml with extracted seed entities when you press Ctrl+C. Point your app at the local proxy, use it normally, and get a config file with realistic data.

Why this matters

Setting up seed data for emulate requires manually writing YAML configs. For APIs with nested relationships (repos with issues, customers with payment methods), this is tedious and the resulting fixtures may not match real API response shapes.

Mockoon and WireMock both have recording proxy modes. This brings the same capability to emulate, with the added benefit of generating emulate-native seed configs rather than generic mock definitions.

Changes

  • packages/emulate/src/commands/record.ts: New command implementing the proxy server, traffic recording, and entity extraction. Includes extractors for GitHub (users, repos from response bodies) and Stripe (customers, products).
  • packages/emulate/src/index.ts: Registered the record command with --service, --upstream, --port, and --output flags
  • README.md and skills/emulate/SKILL.md: documented the new command with examples and flag reference

Demo

record-demo

Shows the recording proxy starting, forwarding a request to GitHub's API, then generating a seed config on shutdown with the extracted user and repo entities.

How it works

  1. Starts a Hono server on the configured port
  2. Every request is forwarded to the --upstream URL with original headers
  3. Response is returned to the caller and recorded in memory
  4. On Ctrl+C, recorded responses are analyzed by service-specific extractors
  5. Extracted entities are written as an emulate.config.yaml

Entity extraction is service-specific. Currently GitHub and Stripe have extractors. Other services proxy correctly but don't extract entities yet.

Testing

Existing tests pass. The proxy and entity extractors are pure functions that can be unit tested independently.

This contribution was developed with AI assistance (Claude Code).

Add `emulate record` command that proxies requests to real APIs,
records the traffic, and generates an emulate.config.yaml with
extracted seed entities on shutdown (Ctrl+C).

Includes entity extractors for GitHub (users, repos) and Stripe
(customers, products). Other services pass through the proxy but
don't extract entities yet.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented Apr 8, 2026

@mvanhorn is attempting to deploy a commit to the Vercel Labs Team on Vercel.

A member of the Team first needs to authorize it.

Comment thread packages/emulate/src/commands/record.ts Outdated
Comment thread packages/emulate/src/commands/record.ts
mvanhorn and others added 2 commits April 8, 2026 10:19
- Wrap upstream fetch() in try/catch to return 502 with error details
  instead of opaque 500 when upstream is unreachable
- Strip trailing slashes from --upstream URL to prevent double-slash
  in constructed request URLs

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@mvanhorn
Copy link
Copy Markdown
Contributor Author

Fixed both findings in 5b655d1:

  • Wrapped the upstream fetch() in try/catch to return a 502 with the error message instead of an opaque 500
  • Normalized --upstream URL by stripping trailing slashes to prevent double-slash in request URLs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant