Skip to content
Runtime
Framework

Server

Adapter

Web-standard `Request` and `URL` helpers for request-scoped decoding.

Package
@queryweave/server
Runtime
Any web-standard server, edge, or worker runtime
Depends on
@queryweave/core
Framework required
No
InstallQuick examplePackage: @queryweave/server
  • Decoding the query of a Request or a URL with a model.
  • Building a canonical query string, or a complete URL, from typed state.
  • Producing a read-only QuerySource scoped to one request.

Navigation. A request is read once and then ends; there is no history to push to. That is why this package produces a QuerySource rather than a QueryAdapter — the capability is absent from the type, not present and throwing.

Request-scoped source — reads once, never navigates

Request-scoped source — reads once, never navigates

  1. Request (incoming)
  2. QuerySource (read-only)
  3. QueryModel.decode() (typed result)

Request → QuerySource. QuerySource → QueryModel.decode().

Read, decode, respond. Nothing in this chain can navigate.
Terminal window
pnpm add @queryweave/core @queryweave/server

No Node built-in is used anywhere in the package, so it runs unchanged on Node.js, Deno, Bun, Cloudflare Workers, and any other runtime with Request and URL.

import { readRequestQuery } from "@queryweave/server";
export async function handler(request: Request): Promise<Response> {
const result = readRequestQuery(request, products);
const values = result.ok ? result.value : { ...products.defaults(), ...result.partial };
return Response.json({
products: await search(values),
issues: result.issues,
});
}

The merge on the second line is the standard pattern: render something useful, and keep the issues for diagnostics.

readUrlQuery(url, model); // string | URL
readRequestQuery(request, model); // Request
await readUrlQueryAsync(url, model); // when validation is asynchronous
await readRequestQueryAsync(request, model);

A relative URL string is accepted. It is resolved against relativeUrlBase (http://queryweave.invalid), which is exported so tests can assert against it. Only the query is ever read, so the base is irrelevant to the result.

const result = readUrlQuery("/products?search=vue&page=2", products);
result.ok; // true
if (result.ok) result.value; // { search: "vue", page: 2, ...defaults }
import { createRequestQuerySource } from "@queryweave/server";
const source = createRequestQuerySource(request);
source.read(); // "?page=2"
source.request; // the original Request

Use this when a helper wants a QuerySource rather than a decoded result — for example, code that should work with any read-only environment.

import { createQueryUrl, encodeQuery } from "@queryweave/server";
encodeQuery(products, { search: "vue", page: 2, sort: "created_at", status: "all" });
// "search=vue&page=2"
createQueryUrl("https://example.com/products?utm_source=email", products, values);
// https://example.com/products?search=vue&page=2&utm_source=email

encodeQuery returns the canonical query string with no leading ?. createQueryUrl returns a URL, and it is the one place outside the runtime that preserves unmanaged keys: managed keys are written first, and everything the model does not declare follows in its original order.

In Server mode the history controls are gone, not merely disabled: there is no stack to move through. Each change represents a new request URL being decoded.

History

Products

6 matching

  • Edge runtime handbookactive$59
  • Node.js request toolkitactive$39
  • Nuxt deployment guidearchived$19
  • Request URL
  • decode
  • typed result
  • canonical URL

A request is read once. There is no history to move through, so navigation is absent.

Type a query, press Enter.

Typed state

{
  "page": 1,
  "sort": "created_at",
  "status": "all"
}

Canonical URL

Valid
/products

    • An absolute URL is used as given. A string that parses as absolute is not re-based.
    • A malformed query does not throw. It decodes with issues, exactly as in the browser.
    • createQueryUrl mutates nothing. It copies the base URL before writing to search.
    • Repeated unmanaged keys keep their order and multiplicity.

    tests/server/server.test.ts covers reading, encoding, and link building, including unmanaged-key preservation and the relative-base fallback. The universal consumer fixture installs the packed archive and runs the same helpers outside the workspace.