### Install and Import Application for Bun (JSR) Source: https://github.com/oakserver/oak/blob/main/README.md Install the @oak/oak package for Bun using jsr and import the Application class. ```bash bunx jsr i @oak/oak ``` ```typescript import { Application } from "@oak/oak/application"; ``` -------------------------------- ### Install and Import Application for Node.js (JSR) Source: https://github.com/oakserver/oak/blob/main/README.md Install the @oak/oak package using jsr and import the Application class for Node.js. ```bash npx jsr i @oak/oak ``` ```javascript import { Application } from "@oak/oak/application"; ``` -------------------------------- ### Install and Import Application for Node.js (npm) Source: https://github.com/oakserver/oak/blob/main/README.md Install the @oakserver/oak package using npm and import the Application class for Node.js. ```bash npm i @oakserver/oak ``` ```javascript import { Application } from "@oakserver/oak"; ``` -------------------------------- ### Basic Oak Application with ES Modules Source: https://github.com/oakserver/oak/blob/main/docs/node.md Use this snippet to start a simple Oak server in Node.js when using ES modules. Ensure you have installed the `@oakserver/oak` package. ```js import { Application } from "@oakserver/oak"; const app = new Application(); app.use((ctx) => { ctx.response.body = "Hello from oak on Node.js"; }); app.listen({ port: 8000 }); ``` -------------------------------- ### Listen for Server Start Event Source: https://github.com/oakserver/oak/blob/main/README.md Register a listener for the 'listen' event to log server startup information. This is useful for confirming the server is running and accessible. ```typescript import { Application } from "@oak/oak/application"; const app = new Application(); app.addEventListener("listen", ({ hostname, port, secure }) => { console.log( `Listening on: ${secure ? "https://" : "http://"}${hostname ?? "localhost"}:${port}`, ); }); // register some middleware await app.listen({ port: 80 }); ``` -------------------------------- ### Basic Oak Application with CommonJS Source: https://github.com/oakserver/oak/blob/main/docs/node.md Use this snippet to start a simple Oak server in Node.js when using CommonJS modules. Ensure you have installed the `@oakserver/oak` package. ```js const { Application } = require("@oakserver/oak"); const app = new Application(); app.use((ctx) => { ctx.response.body = "Hello from oak on Node.js"; }); app.listen({ port: 8000 }); ``` -------------------------------- ### Basic SSE endpoint setup Source: https://github.com/oakserver/oak/blob/main/docs/sse.md Sets up a basic SSE endpoint that dispatches a simple JSON message to the client. Requires importing Application and Router from Oak. ```typescript import { Application, Router } from "https://deno.land/x/oak/mod.ts"; const app = new Application(); const router = new Router(); router.get("/sse", async (ctx) => { const target = await ctx.sendEvents(); target.dispatchMessage({ hello: "world" }); }); app.use(router.routes()); await app.listen({ port: 80 }); ``` -------------------------------- ### Create a Basic "Hello World" Server with Oak Source: https://github.com/oakserver/oak/blob/main/docs/main.md This snippet demonstrates how to create a simple Oak server that responds with "Hello world!". Ensure you have Deno installed and the necessary network permissions. ```typescript import { Application } from "https://deno.land/x/oak/mod.ts"; const app = new Application(); app.use((ctx) => { ctx.response.body = "Hello world!"; }); await app.listen({ port: 8000 }); ``` -------------------------------- ### Basic "Hello World!" Application Source: https://github.com/oakserver/oak/blob/main/README.md A simple Oak application that responds with "Hello World!" to all requests. Use this as a starting point for new Oak projects. Requires network permissions. ```ts import { Application } from "@oak/oak/application"; const app = new Application(); app.use((ctx) => { ctx.response.body = "Hello World!"; }); await app.listen({ port: 8000 }); ``` -------------------------------- ### Nested Routers Source: https://github.com/oakserver/oak/blob/main/README.md Demonstrates how to nest routers to handle more complex routing structures. This example handles requests for forum posts. ```APIDOC ## GET /forums/:forumId/posts ### Description Returns the forum ID. ### Method GET ### Endpoint /forums/:forumId/posts ### Parameters #### Path Parameters - **forumId** (string) - Required - The ID of the forum. ## GET /forums/:forumId/posts/:postId ### Description Returns the forum ID and post ID. ### Method GET ### Endpoint /forums/:forumId/posts/:postId ### Parameters #### Path Parameters - **forumId** (string) - Required - The ID of the forum. - **postId** (string) - Required - The ID of the post. ``` -------------------------------- ### Running a Deno Application Source: https://github.com/oakserver/oak/blob/main/README.md Command to execute a Deno TypeScript file that requires network access. Ensure you have Deno installed. ```bash > deno run --allow-net helloWorld.ts ``` -------------------------------- ### Complex Middleware Stack Example Source: https://github.com/oakserver/oak/blob/main/README.md An Oak application demonstrating a middleware stack with logging and response time tracking. Each middleware calls 'await next()' to pass control to the next in the stack. ```ts import { Application } from "@oak/oak/application"; const app = new Application(); // Logger app.use(async (ctx, next) => { await next(); const rt = ctx.response.headers.get("X-Response-Time"); console.log(`${ctx.request.method} ${ctx.request.url} - ${rt}`); }); // Timing app.use(async (ctx, next) => { const start = Date.now(); await next(); const ms = Date.now() - start; ctx.response.headers.set("X-Response-Time", `${ms}ms`); }); // Hello World! app.use((ctx) => { ctx.response.body = "Hello World!"; }); await app.listen({ port: 8000 }); ``` -------------------------------- ### Install and Import Application for Cloudflare Workers (JSR) Source: https://github.com/oakserver/oak/blob/main/README.md Install the @oak/oak package for Cloudflare Workers using jsr and import the Application class. ```bash npx jsr add @oak/oak ``` ```typescript import { Application } from "@oak/oak/application"; ``` -------------------------------- ### Basic RESTful API Routing Source: https://github.com/oakserver/oak/blob/main/README.md Set up a router to handle GET requests for a collection of books and individual books by ID. Uses `router.routes()` and `router.allowedMethods()` middleware. ```typescript import { Application } from "@oak/oak/application"; import { Router } from "@oak/oak/router"; const books = new Map(); books.set("1", { id: "1", title: "The Hound of the Baskervilles", author: "Conan Doyle, Arthur", }); const router = new Router(); router .get("/", (context) => { context.response.body = "Hello world!"; }) .get("/book", (context) => { context.response.body = Array.from(books.values()); }) .get("/book/:id", (context) => { if (books.has(context?.params?.id)) { context.response.body = books.get(context.params.id); } }); const app = new Application(); app.use(router.routes()); app.use(router.allowedMethods()); await app.listen({ port: 8000 }); ``` -------------------------------- ### Minimal Cloudflare Worker Server with Oak Source: https://github.com/oakserver/oak/blob/main/README.md A basic Oak application setup for Cloudflare Workers that responds to requests with 'Hello CFW!'. ```typescript import { Application } from "@oak/oak/application"; const app = new Application(); app.use((ctx) => { ctx.response.body = "Hello CFW!"; }); export default { fetch: app.fetch }; ``` -------------------------------- ### Basic Router Usage Source: https://github.com/oakserver/oak/blob/main/README.md Defines a RESTful service for books using GET requests. It handles requests for the root path, a list of all books, and a specific book by ID. ```APIDOC ## GET / ### Description Serves a "Hello world!" response. ### Method GET ### Endpoint / ## GET /book ### Description Returns an array of all books. ### Method GET ### Endpoint /book ## GET /book/:id ### Description Returns a specific book by its ID. ### Method GET ### Endpoint /book/:id ### Parameters #### Path Parameters - **id** (string) - Required - The ID of the book to retrieve. ``` -------------------------------- ### Handling Static Content Response with Router Source: https://github.com/oakserver/oak/blob/main/docs/FAQ.md Example of serving static content with the router where `next()` is not explicitly called, demonstrating a scenario where flow control is dropped. ```typescript import { Application, Router } from "https://deno.land/x/oak/mod.ts"; const router = new Router(); router.get("/", (ctx) => { ctx.response.body = "hello world"; }); const app = new Application(); app.use(router.routes()); app.use(router.allowedMethods()); app.listen(); ``` -------------------------------- ### Handling Requests with .handle() Source: https://github.com/oakserver/oak/blob/main/README.md An example of using the .handle() method to process requests without managing the server directly. This is an advanced usage pattern. It returns a Response object or undefined. ```ts import { Application } from "@oak/oak/application"; const app = new Application(); app.use((ctx) => { ctx.response.body = "Hello World!"; }); Deno.serve(async (request, info) => { const res = await app.handle(request, info.remoteAddr); return res ?? Response.error(); }); ``` -------------------------------- ### Listening for Uncaught Errors Source: https://github.com/oakserver/oak/blob/main/README.md Catch uncaught exceptions dispatched as 'error' events on the application instance. This example logs the error and forces a 500 status on all requests. ```typescript import { Application } from "@oak/oak/application"; const app = new Application(); app.addEventListener("error", (evt) => { // Will log the thrown error to the console. console.log(evt.error); }); app.use((ctx) => { // Will throw a 500 on every request. ctx.throw(500); }); await app.listen({ port: 80 }); ``` -------------------------------- ### Run a Deno Server with Network Permissions Source: https://github.com/oakserver/oak/blob/main/docs/main.md This command is used to execute a Deno TypeScript file that requires network access. The `--allow-net` flag grants the necessary permissions. ```shell deno run --allow-net server.ts ``` -------------------------------- ### Adapt Deno.serve() Handler with Oak's serve Middleware Source: https://github.com/oakserver/oak/blob/main/README.md Use the `serve` middleware to adapt handlers written for `Deno.serve()` or the Fetch API. It provides a Fetch API `Request` and expects a Fetch API `Response`. ```typescript import { Application } from "@oak/oak/application"; import { serve } from "@oak/oak/serve"; const app = new Application(); app.use(serve((req, ctx) => { console.log(req.url); return new Response("Hello world!"); })); app.listen(); ``` -------------------------------- ### Import Application for Deno CLI/Deploy Source: https://github.com/oakserver/oak/blob/main/README.md Import the Application class from the oak library for use with Deno CLI or Deno Deploy. ```typescript import { Application } from "https://deno.land/x/oak/mod.ts"; ``` -------------------------------- ### Create domains.txt for Subject Alternative Names Source: https://github.com/oakserver/oak/blob/main/examples/tls/README.md Defines the Subject Alternative Names (SANs) for the domain certificate, specifying which domain names the certificate will be valid for. ```shell authorityKeyIdentifier=keyid,issuer basicConstraints=CA:FALSE keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment subjectAltName = @alt_names [alt_names] DNS.1 = localhost ``` -------------------------------- ### Serve Static Content with Oak Source: https://github.com/oakserver/oak/blob/main/README.md Use the `send()` function to serve static files from a specified root directory. It automatically handles ETag and Last-Modified headers for caching. ```typescript import { Application } from "@oak/oak/application"; const app = new Application(); app.use(async (context, next) => { try { await context.send({ root: `${Deno.cwd()}/examples/static`, index: "index.html", }); } catch { await next(); } }); await app.listen({ port: 8000 }); ``` -------------------------------- ### Performing a Redirect with Oak Source: https://github.com/oakserver/oak/blob/main/docs/FAQ.md Shows how to perform a client-side redirect to a specified URL using the `ctx.response.redirect()` method. ```typescript import { Application } from "https://deno.land/x/oak/mod.ts"; const app = new Application(); app.use((ctx) => { ctx.response.redirect("https://deno.land/"); }); await app.listen({ port: 8000 }); ``` -------------------------------- ### Connect to SSE and Display Messages Source: https://github.com/oakserver/oak/blob/main/examples/resources/sseServer_index.html Connects to the SSE endpoint and appends incoming messages to an unordered list. Ensure an element with id 'events' exists in the HTML. ```javascript const sse = new EventSource("/sse"); const ul = document.getElementById("events"); sse.onmessage = (evt) => { const li = document.createElement("li"); li.textContent = `message: ${evt.data}`; ul.appendChild(li); }; ``` -------------------------------- ### Import Application for JSR (Deno) Source: https://github.com/oakserver/oak/blob/main/README.md Import the Application class from the oak library for use with JSR in a Deno project. ```typescript import { Application } from "@oak/oak"; ``` -------------------------------- ### Redirecting to Referrer or Backup URL Source: https://github.com/oakserver/oak/blob/main/docs/FAQ.md Illustrates how to redirect a request back to the referrer URL or a specified backup URL if the referrer is not available. ```typescript import { Application, REDIRECT_BACK } from "https://deno.land/x/oak/mod.ts"; const app = new Application(); app.use((ctx) => { ctx.response.redirect(REDIRECT_BACK, "/home"); }); await app.listen({ port: 8000 }); ``` -------------------------------- ### Handling client close event Source: https://github.com/oakserver/oak/blob/main/docs/sse.md Demonstrates how to listen for the 'close' event on the server-side SSE target to perform cleanup activities when the client disconnects. ```typescript router.get("/sse", async (ctx) => { const target = await ctx.sendEvents(); target.addEventListener("close", (evt) => { // perform some cleanup activities }); target.dispatchMessage({ hello: "world" }); }); ``` -------------------------------- ### Nested Routers for Forum Posts Source: https://github.com/oakserver/oak/blob/main/README.md Demonstrates nesting routers to handle hierarchical routes like `/forums/:forumId/posts`. Uses `posts.routes()` and `posts.allowedMethods()` within a parent router. ```typescript import { Application } from "@oak/oak/application"; import { Router } from "@oak/oak/router"; const posts = new Router() .get("/", (ctx) => { ctx.response.body = `Forum: ${ctx.params.forumId}`; }) .get("/:postId", (ctx) => { ctx.response.body = `Forum: ${ctx.params.forumId}, Post: ${ctx.params.postId}`; }); const forums = new Router().use( "/forums/:forumId/posts", posts.routes(), posts.allowedMethods(), ); await new Application().use(forums.routes()).listen({ port: 8000 }); ``` -------------------------------- ### Client-side EventSource connection Source: https://github.com/oakserver/oak/blob/main/docs/sse.md The client initiates an SSE connection by creating an EventSource object pointing to a server path. ```javascript const eventSource = new EventSource("/sse"); ``` -------------------------------- ### Closing an Oak Server with AbortController Source: https://github.com/oakserver/oak/blob/main/docs/FAQ.md Demonstrates how to close an Oak server gracefully using the AbortController. The server is configured to close after the first request is processed. ```typescript import { Application } from "https://deno.land/x/oak/mod.ts"; const app = new Application(); const controller = new AbortController(); const { signal } = controller; app.use((ctx) => { // after first request, the server will be closed controller.abort(); }); await app.listen({ port: 8000, signal }); console.log("Server closed."); ``` -------------------------------- ### Request Object Methods Source: https://github.com/oakserver/oak/blob/main/README.md The `context.request` object offers methods for content negotiation, allowing developers to determine the client's supported content types, encodings, and languages. ```APIDOC ## Request Object Methods ### Description The `context.request` object provides several methods for content negotiation, enabling the server to understand and respond to the client's preferences for content type, encoding, and language. ### Methods - **`.accepts(...types: string[])`**: Negotiates the content type supported by the request. If types are provided, it returns the best negotiated content type; otherwise, it returns a prioritized array of accepted content types. Returns `undefined` if no match is found. - **`.acceptsEncodings(...encodings: string[])`**: Negotiates the content encoding supported by the request. If encodings are provided, it returns the best negotiated encoding; otherwise, it returns a prioritized array of accepted encodings. Returns `undefined` if no match is found. - **`.acceptsLanguages(...languages: string[])`**: Negotiates the language the client is able to understand. If languages are provided, it returns the best negotiated language; otherwise, it returns a prioritized array of understood languages. Returns `undefined` if no match is found. ``` -------------------------------- ### Import Oak Testing Utilities Source: https://github.com/oakserver/oak/blob/main/docs/testing.md Import the testing namespace from Oak's mod.ts to access mocking utilities. ```typescript import { testing } from "https://deno.land/x/oak/mod.ts"; ``` -------------------------------- ### Generate Root CA Certificate and Key Source: https://github.com/oakserver/oak/blob/main/examples/tls/README.md Creates a self-signed root CA certificate and its private key. This CA will be used to sign domain certificates. ```shell openssl req -x509 -nodes -new -sha256 -days 36135 -newkey rsa:2048 -keyout RootCA.key -out RootCA.pem -subj "/C=US/CN=Example-Root-CA" openssl x509 -outform pem -in RootCA.pem -out RootCA.crt ``` -------------------------------- ### Adapt Router Handlers with Oak's route Middleware Source: https://github.com/oakserver/oak/blob/main/README.md Use the `route` middleware to adapt router handlers for use with Oak, similar to `Deno.serve()`. It provides access to router parameters via the context. ```typescript import { Application } from "@oak/oak/application"; import { Router } from "@oak/oak/router"; import { route } from "@oak/oak/serve"; const app = new Application; const router = new Router(); router.get("/books/:id", route((req, ctx) => { console.log(ctx.params.id); return Response.json({ title: "hello world", id: ctx.params.id }); })); app.use(router.routes()); app.listen(); ``` -------------------------------- ### MockContextOptions Interface Source: https://github.com/oakserver/oak/blob/main/docs/testing.md Defines the options available for creating a mock context, including application, method, parameters, path, and state. ```typescript export interface MockContextOptions< P extends RouteParams = RouteParams, S extends State = Record, > { app?: Application; method?: string; params?: P; path?: string; state?: S; } ``` -------------------------------- ### Mock Middleware Execution and Assertion Source: https://github.com/oakserver/oak/blob/main/docs/testing.md Test middleware by creating a mock context and next function, executing the middleware, and asserting against the response. Ensure the request path matches '/a' to set the body and a header. ```typescript import { testing } from "https://deno.land/x/oak/mod.ts"; import type { Middleware } from "https://deno.land/x/oak/mod.ts"; import { assert, assertEquals } from "https://deno.land/std/testing/asserts.ts"; const mw: Middleware = async (ctx, next) => { await next(); if (ctx.request.url.pathname === "/a") { ctx.response.body = "Hello a"; ctx.response.headers.set("x-hello-a", "hello"); } }; Deno.test({ name: "example test", async fn() { const ctx = testing.createMockContext({ path: "/a", }); const next = testing.createMockNext(); await mw(ctx, next); assertEquals(ctx.response.body, "Hello a"); assert(ctx.response.headers.has("x-hello-a")); }, }); ``` -------------------------------- ### Client-side listening for custom SSE events Source: https://github.com/oakserver/oak/blob/main/docs/sse.md The client listens for a custom-named SSE event ('ping') and logs the received data. The data is automatically parsed as JSON if applicable. ```javascript const source = new EventSource("/sse"); source.addEventListener("ping", (evt) => { console.log(evt.data); // should log a string of `{"hello":"world"}` }); ``` -------------------------------- ### Generate Domain Certificate Signed by Root CA Source: https://github.com/oakserver/oak/blob/main/examples/tls/README.md Generates a private key and a Certificate Signing Request (CSR) for a domain, then signs it using the root CA to create the final domain certificate. ```shell openssl req -new -nodes -newkey rsa:2048 -keyout localhost.key -out localhost.csr -subj "/C=US/ST=YourState/L=YourCity/O=Example-Certificates/CN=localhost.local" openssl x509 -req -sha256 -days 36135 -in localhost.csr -CA RootCA.pem -CAkey RootCA.key -CAcreateserial -extfile domains.txt -out localhost.crt ``` -------------------------------- ### Logging Middleware After Execution Source: https://github.com/oakserver/oak/blob/main/docs/main.md Use this pattern when you need to perform actions after all other middleware has completed, such as logging. The await next() ensures subsequent middleware runs before the current function's remaining code. ```typescript const app = new Application(); app.use(async (ctx, next) => { await next(); /* Do some cool logging stuff here */ }); ``` -------------------------------- ### Managing Custom State in Oak Application Source: https://github.com/oakserver/oak/blob/main/docs/FAQ.md Demonstrates how to define and manage custom state within an Oak application using generics for strong typing. State is typically set in middleware and cleaned up afterwards. ```typescript import { Application } from "https://deno.land/x/oak/mod.ts"; interface MyState { userId: number; } const app = new Application(); app.use(async (ctx, next) => { // do whatever checks to determine the user ID ctx.state.userId = userId; await next(); delete ctx.state.userId; // cleanup }); app.use(async (ctx, next) => { // now the state.userId will be set for the rest of the middleware ctx.state.userId; await next(); }); await app.listen(); ``` -------------------------------- ### Explicitly Invoking next() in Middleware Source: https://github.com/oakserver/oak/blob/main/docs/FAQ.md Demonstrates the recommended practice of always invoking `next()` in middleware to maintain explicit control over the middleware flow and prevent response writability errors. ```typescript import { Application, Router } from "https://deno.land/x/oak/mod.ts"; const router = new Router(); router.get("/", (ctx, next) => { ctx.response.body = "hello world"; return next(); }); const app = new Application(); app.use(router.routes()); app.use(router.allowedMethods()); app.listen(); ``` -------------------------------- ### ETag Support Middleware for Oak Source: https://github.com/oakserver/oak/blob/main/README.md Integrate the `etag` factory middleware to automatically generate ETag headers for static assets, enabling client-side caching. ```typescript import { Application } from "@oak/oak/application"; import { factory } from "@oak/oak/etag"; const app = new Application(); app.use(factory()); // ... other middleware for the application ``` -------------------------------- ### Dispatching custom SSE events Source: https://github.com/oakserver/oak/blob/main/docs/sse.md Illustrates dispatching a custom-named ServerSentEvent with a payload. The client will receive this as a MessageEvent with the specified event name. ```typescript router.get("/sse", async (ctx: Context) => { const target = await ctx.sendEvents(); const event = new ServerSentEvent("ping", { hello: "world" }); target.dispatchEvent(event); }); ``` -------------------------------- ### Request Object Properties Source: https://github.com/oakserver/oak/blob/main/README.md The `context.request` object provides access to various properties of an incoming HTTP request, including its body, headers, method, and URL. ```APIDOC ## Request Object Properties ### Description The `context.request` object contains information about the request. It provides access to properties such as the request body, headers, method, and URL. ### Properties - **`.body`**: Provides access to the request body. - **`.hasBody`**: A boolean indicating if the request might have a body. Note: This API is unreliable for determining body presence in HTTP/2 and some HTTP/1.1 scenarios. - **`.headers`**: An instance of the `Headers` interface for accessing request headers. - **`.method`**: A string representing the HTTP method of the request. - **`.originalRequest`**: **DEPRECATED**. The raw native server request object. - **`.secure`**: A boolean shortcut for `.protocol`, returning `true` if the request is HTTPS. - **`.source`**: When running under Deno, this is the source web standard `Request`. It is `undefined` when running under NodeJS. - **`.url`**: An instance of `URL` representing the full URL of the request. ``` -------------------------------- ### Checking client's SSE acceptance Source: https://github.com/oakserver/oak/blob/main/docs/sse.md Ensures the client request explicitly accepts the 'text/event-stream' content type, which is standard for SSE connections. ```typescript ctx.request.accepts("text/event-stream"); ``` -------------------------------- ### Calculate ETag from Context Entity in Oak Source: https://github.com/oakserver/oak/blob/main/README.md Manually calculate an ETag for a response body using `getEntity` and `calculate` from Deno's std library. This is useful when the response body is already set. ```typescript import { Application } from "@oak/oak/application"; import { getEntity } from "@oak/oak/etag"; import { calculate } from "@std/http/etag"; const app = new Application(); // The context.response.body has already been set... app.use(async (ctx) => { const entity = await getEntity(ctx); if (entity) { const etag = await calculate(entity); } }); ``` -------------------------------- ### Close Oak Server with AbortSignal Source: https://github.com/oakserver/oak/blob/main/README.md Gracefully shut down the Oak server by aborting an AbortSignal passed to the listen method. The listen promise resolves when the server has stopped accepting new requests. ```typescript import { Application } from "@oak/oak/application"; const app = new Application(); const controller = new AbortController(); const { signal } = controller; // Add some middleware using `app.use()` const listenPromise = app.listen({ port: 8000, signal }); // In order to close the server... controller.abort(); // Listen will stop listening for requests and the promise will resolve... await listenPromise; // and you can do something after the close to shutdown ``` -------------------------------- ### Request Body Properties and Methods Source: https://github.com/oakserver/oak/blob/main/README.md Oak's request body API provides properties to check for a body's existence and usage, a stream for reading raw body data, and methods to parse the body into various formats like JSON, form data, text, or binary. ```APIDOC ## Request Body API ### Description Oak's request body API is inspired by the Fetch API's `Request` object, offering properties and methods to interact with the incoming request body. ### Properties - **`.has`** (boolean) - `true` if the request might have a body, `false` otherwise. Note: This can be unreliable in HTTP/2 due to streaming. - **`.stream`** (`ReadableStream`) - A stream for reading the body in `Uint8Array` chunks, similar to `Fetch API`'s `Request.body`. - **`.used`** (boolean) - `true` if the body has already been read, `false` otherwise. ### Methods - **`arrayBuffer()`** - Resolves with an `ArrayBuffer` containing the body's contents. Suitable for binary data. - **`blob()`** - Resolves with a `Blob` containing the body's contents. Suitable for binary data. - **`form()`** - Resolves with a `URLSearchParams` decoded from the body. Appropriate for `application/x-www-form-urlencoded` content types. - **`formData()`** - Resolves with a `FormData` instance decoded from the body. Appropriate for `multipart/form-data` content types. - **`json()`** - Resolves with the body's content parsed as JSON. Optionally uses a `jsonBodyReviver` if specified. - **`text()`** - Resolves with a string representing the body's contents. - **`type(customMediaTypes?: object)`** - Attempts to determine the body's encoding type and returns a string indicating how to decode it. Accepts an optional `customMediaTypes` object to influence type detection. - Possible return values: `"binary"`, `"form"`, `"form-data"`, `"json"`, `"text"`, `"unknown"`. - The `customMediaTypes` object can map types (`binary`, `form`, `form-data`, `json`, `text`) to media types compatible with the [type-is format](https://github.com/jshttp/type-is/?tab=readme-ov-file#typeisrequest-types). ``` -------------------------------- ### Request Processing and Response Finalization Middleware Source: https://github.com/oakserver/oak/blob/main/docs/main.md This pattern is useful for processing requests, like validating session IDs, before allowing other middleware to run. It then allows for finalization of the response after subsequent middleware has completed. ```typescript app.use(async (ctx, next) => { /* Do some checking of the request */ await next(); /* Do some finalising of the response */ }); ``` -------------------------------- ### Server-side closing SSE connection Source: https://github.com/oakserver/oak/blob/main/docs/sse.md Shows how the server can explicitly close the Server-Sent Events connection after sending a message. ```typescript router.get("/sse", async (ctx) => { const target = await ctx.sendEvents(); target.dispatchMessage({ hello: "world" }); await target.close(); }); ``` -------------------------------- ### Trapping Errors with Middleware Source: https://github.com/oakserver/oak/blob/main/README.md Use middleware to catch and handle errors, providing custom responses for HTTP errors. Rethrow errors that cannot be handled. ```typescript import { Application } from "@oak/oak/application"; import { isHttpError } from "@oak/commons/http_errors"; import { Status } from "@oak/commons/status"; const app = new Application(); app.use(async (ctx, next) => { try { await next(); } catch (err) { if (isHttpError(err)) { switch (err.status) { case Status.NotFound: // handle NotFound break; default: // handle other statuses } } else { // rethrow if you can't handle the error throw err; } } }); ``` -------------------------------- ### Customizing SSE response headers Source: https://github.com/oakserver/oak/blob/main/docs/sse.md Allows overriding default SSE response headers or adding custom headers by passing a Headers object to sendEvents(). ```typescript router.get("/sse", async (ctx: Context) => { const headers = new Headers([["X-Custom-Header", "custom value"]]); const target = await ctx.sendEvents({ headers }); const event = new ServerSentEvent("ping", { hello: "world" }); target.dispatchEvent(event); }); ``` -------------------------------- ### Disabling Automatic Error Logging in Oak Source: https://github.com/oakserver/oak/blob/main/docs/FAQ.md Set `logErrors` to `false` in the `Application` options to disable automatic logging of uncaught errors. Alternatively, register a custom error handler using `.addEventListener("error", (evt) => {});`. ```typescript const app = new Application({ logErrors: false, }); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.