Skip to content

v0.6.3

Latest

Choose a tag to compare

@github-actions github-actions released this 06 Oct 21:26
· 1 commit to main since this release
v0.6.3
1b98554

Added

  • @tetsujs/static, a new package: staticFiles() serves the files of a directory from fallback or a route, a built site, a single-page app or assets, inside the pipeline, so the application's hooks apply to them. A path is checked before the disk is touched, a directory is redirected to its trailing slash, a file has ETag and Last-Modified with 304, and Bun answers Range. notFound sends a page of the site to a browser, spa the app's shell, and precompressed the .br or .gz copy beside a file. The route stays out of the OpenAPI document unless it says docs: { hidden: false } (#74).
  • @tetsujs/core: a status of a response map can name the media type of a body that is not JSON — { 200: { contentType: "text/csv", body } } — for a status the handler answers with a Response it builds: a file, a CSV export, sse(). Returning a value for it, or nothing, is a compile error, since a value would leave as JSON and nothing as an empty body; a type the compiler knows only as a string counts as not JSON, and where it does not see the key at all, it is a 500 when responses are validated. route() refuses a content type that is not a bare type or range, such as one with a charset.
  • @tetsujs/openapi: such a status is documented under its own media type, with its body as the schema, instead of application/json. So is a response documented() gives a hook, with a contentType of its own; documented() refuses one that is not a bare type or range.
  • @tetsujs/openapi: documented() annotates a handler as it does a hook, so a package's handler describes every route that mounts it. Its responses are the route's own, and hidden: true keeps the route out of the document unless the route says docs: { hidden: false }.
  • @tetsujs/openapi: assertDescribed takes a body under a range of media types, such as image/* or */*, and compares types without regard to case. It parses a body as JSON only under application/json or a +json type, and takes an empty body under any other.

Fixed

  • @tetsujs/core: a route with a query schema answers a request without a usable Host, such as an HTTP/1.0 health check, instead of failing it with a 500. Bun leaves req.url relative then, and the query is read against a placeholder origin. A Host such as [ makes req.url no URL at all, and such a request has no query.
  • @tetsujs/request-log: for the same requests, arrivalLog() no longer turns the request into a 500, and accessLog() writes its record instead of reporting a failure. The path is read from a relative req.url too, and a req.url that is no URL is written as it came, up to its query.
  • @tetsujs/core: a response map keyed by anything but a status, a range such as 4XX or default, or with an entry that is neither a schema, null nor an object of parts, is refused where the route is declared. It passed: a key such as 600 matched no response and was documented as one, an entry such as a bare string made every validated response of its status a 500, an undefined entry went unchecked, and openapi() threw a TypeError on either of the last two. default and the ranges, OpenAPI's own keys, are taken as before: they are documented, and declare no status a response may leave with.
  • @tetsujs/openapi: a response a hook documents below 400 without a schema has no body in the document — a redirect, or the refusal of a secured() hook that sends to a sign-in page. It was described as the error envelope.
  • @tetsujs/openapi: the responses hooks document are no longer merged by status and description. Two guards that answer 403 Forbidden with codes of their own, such as NOT_OWNER and PLAN_LIMIT, are both documented, where the second was dropped; a description that a coded response already gives is said once; and two definitions of one code with different fields give a warning, where one was dropped without a word.
  • @tetsujs/openapi: default and a range such as 4XX in a response map are described as what they are, Any other response and Client error, not as HTTP NaN.

Full Changelog: v0.6.2...v0.6.3