
Research
/Security News
PolinRider Spreads Through Compromised GitHub Accounts and Packagist
Operators behind PolinRider used a compromised GitHub account to plant malware in four development versions of a Packagist package with 700,000+ downloads.
@danmat/query-fetch
Advanced tools
A tiny, dependency-free client for the HTTP QUERY method (RFC 10008) — the safe, idempotent request with a body. Content-Type enforcement, POST fallback, and Accept negotiation over native fetch.
A tiny, dependency-free client for the HTTP QUERY method (RFC 10008) — the request that is safe and idempotent like GET, but carries a body like POST, and caches like neither before it could.
Built on native fetch. Works in Node 18+, Deno, Bun, Cloudflare Workers, and the browser.
import { query } from "@danmat/query-fetch";
const res = await query("https://api.example.com/search", {
json: { filter: { status: "active" }, sort: "-createdAt", limit: 50 },
});
For years you had two bad options for a search endpoint:
GET with a query string — safe, idempotent, cacheable… but your filter blows past URL length limits and leaks into logs.POST with a body — room for a rich query… but it's neither safe, idempotent, nor cacheable, so proxies and clients treat it as a state change.QUERY is the missing third option: a body-carrying request that intermediaries may cache and clients may safely retry. This library handles the sharp edges the spec introduces.
npm install @danmat/query-fetch
Scripted fetch(url, { method: "QUERY", body }) already works in modern runtimes — but the semantics of RFC 10008 are on you. This library covers them:
Content-Type — the RFC requires servers to reject a QUERY whose body has no content type. We throw before the round-trip instead of letting you debug a 400.POST fallback — servers that don't understand QUERY yet respond 405/501; we automatically retry as POST and advertise the original method via X-HTTP-Method-Override so override-aware backends still route it correctly.Accept negotiation — pass a media type (or list) to negotiate the response format the RFC's Accept-Query dance is built around.303 See Other indirect-result pattern is handled by fetch's own redirect following; nothing surprising here.import { queryJson } from "@danmat/query-fetch";
const { data, response } = await queryJson<{ total: number }>(
"https://api.example.com/search",
{ json: { q: "http query method" } },
);
console.log(data.total, response.headers.get("age"));
queryJson sets Accept: application/json, throws on a non-2xx status, and returns the parsed body alongside the raw Response.
await query("https://api.example.com/search", {
body: "SELECT * WHERE status = 'active'",
contentType: "application/sql",
accept: "application/json",
});
await query(url, { json, fallbackToPost: false });
fetchimport { fetch as undiciFetch } from "undici";
await query(url, { json, fetch: undiciFetch });
query(input, options?): Promise<Response>Performs a QUERY request. options extends RequestInit (so signal, credentials, redirect, etc. all work), minus method and with a richer body:
| Option | Type | Default | Description |
|---|---|---|---|
body | BodyInit | null | — | Raw query body. Pair with contentType. |
json | unknown | — | Value serialized to JSON; sets application/json. |
contentType | string | — | MIME type of body. Required when a body is present. |
accept | string | string[] | — | Sets the Accept header. |
fallbackToPost | boolean | true | Retry as POST on 405/501. |
methodOverrideHeader | string | false | "X-HTTP-Method-Override" | Header advertising the original method on fallback. |
fetch | typeof fetch | globalThis.fetch | Custom fetch implementation. |
queryJson<T>(input, options?): Promise<{ data: T; response: Response }>query + JSON parsing + a non-2xx guard.
QueryErrorThrown for construction-time problems (a body without a content type, no available fetch) and non-2xx responses in queryJson.
QUERY is a Proposed Standard (June 2026). Two things to know:
OPTIONS accordingly.@danmat QUERY suite@danmat/query-fetch — client for the QUERY method (you are here).@danmat/accept-query — parse/build/negotiate the Accept-Query header.@danmat/query-cache — body-aware response caching.@danmat/query-server — server-side request validation & negotiation.▶️ See them work together: query-suite-example — a runnable demo using all four, with a 🌐 live playground.
MIT © Dan Matthew
FAQs
A tiny, dependency-free client for the HTTP QUERY method (RFC 10008) — the safe, idempotent request with a body. Content-Type enforcement, POST fallback, and Accept negotiation over native fetch.
The npm package @danmat/query-fetch receives a total of 9 weekly downloads. As such, @danmat/query-fetch popularity was classified as not popular.
We found that @danmat/query-fetch demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.

Research
/Security News
Operators behind PolinRider used a compromised GitHub account to plant malware in four development versions of a Packagist package with 700,000+ downloads.

Security News
GitHub Actions now supports cache-mode, a least-privilege control on the Actions cache aimed at the cache poisoning technique behind recent compromises.

Company News
Allow myself to introduce... myself.