Both token requests opened HttpResponse.bodyPath with readFileSync, which
ties the plugin to bodies living on a filesystem. The send now hands the body
back, so they read it from there and keep working once bodies move into the
blob DB and in the browser Worker, where there is no fs to read.
text() on a response with no body returns "", which is what the bodyPath
check produced, so an empty response still parses to {} rather than throwing.
Holding an unsaved body against its response id let a plugin stash the id
and read it in a later call, which would throw only sometimes and only
for ad-hoc sends. Documenting that was never going to be enough.
send now returns the response and its body together, so there is nothing
to stash: an unsaved body is a value you were handed. ctx.httpResponse
.body() goes back to meaning one thing, a saved response read by id, and
refuses ids it has no row for. Reading is identical either way, so no
caller has to know which kind of send it made.
A send with no request behind it — a plugin's ad-hoc ctx.httpRequest.send,
GraphQL introspection — gets a generated id and a body file, but no row.
Resolving purely through the database refused those, which would have
broken auth-oauth2 the moment it moved off readFileSync, since every
request it sends is ad-hoc.
The store now falls back to the response directory when there is no row,
accepting only ids shaped the way the engine generates them. Such a
response has no stored headers, so contentType is null and text()
decodes as UTF-8 — which is what the filesystem readers did anyway.
Plugins read bodies by response id through ctx.httpResponse.body()
instead of opening HttpResponse.bodyPath themselves. The accessors are
named after fetch's, minus the single-use semantics, since the bytes are
durable and re-reading should work.
Underneath is a chunked pull over the existing plugin protocol, so the
host can move bodies off the filesystem without plugins noticing.
text() now decodes with the response's charset rather than assuming
UTF-8, and the buffering accessors refuse past 32 MiB and point at
chunks().
Add .oxfmtignore to skip generated bindings and wasm-pack output.
Add npm format script, update DEVELOPMENT.md for Vite+ toolchain,
and format all non-generated files with oxfmt.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace the brittle count assertion (toBe(226)) with a snapshot of all
exported function names. This catches accidental additions, removals,
or renames across faker upgrades with a clear diff.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add body, bodyType, authentication, and authenticationType fields to create/update HTTP request MCP tools
- Include comprehensive documentation for body structures and auth types in Zod descriptions
- Fix MCP update_http_request to merge partial updates with existing data to prevent FK constraint violations
- Fix Zod imports from 'zod/v4' to 'zod' to match installed version
- Add uncaughtException handler to plugin runtime to prevent individual plugin crashes from crashing entire runtime