Skip to content

Commit

Permalink
docs: add basic jsdocs for utils
Browse files Browse the repository at this point in the history
  • Loading branch information
pi0 committed Feb 23, 2024
1 parent ddffb0e commit c8aa150
Show file tree
Hide file tree
Showing 18 changed files with 385 additions and 19 deletions.
2 changes: 1 addition & 1 deletion docs/.config/docs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ description:
in any JavaScript runtime.
github: unjs/h3
url: https://h3.unjs.io
automd: true
# automd: true # HMR seems unstable
redirects: {}
landing:
heroLinks:
Expand Down
47 changes: 47 additions & 0 deletions docs/2.utils/1.request.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,42 +6,89 @@

### `assertMethod(event, expected, allowHead?)`

Asserts that the incoming request method is of the expected type using `isMethod`.
If the method is not allowed, it will throw a 405 error with the message "HTTP method is not allowed".

### `getHeader(event, name)`

Get a request header by name.

### `getHeaders(event)`

Get the request headers object.
Array headers are joined with a comma.

### `getQuery(event)`

Get query the params object from the request URL parsed with [unjs/ufo](https://ufo.unjs.io).

### `getRequestHeader(event, name)`

Get a request header by name.

### `getRequestHeaders(event)`

Get the request headers object.
Array headers are joined with a comma.

### `getRequestHost(event, opts: { xForwardedHost? })`

Get the request hostname.
If `xForwardedHost` is `true`, it will use the `x-forwarded-host` header if it exists.
If no host header is found, it will default to "localhost".

### `getRequestIP(event)`

Try to get the client IP address from the incoming request.
If `xForwardedFor` is `true`, it will use the `x-forwarded-for` header if it exists.

### `getRequestProtocol(event, opts: { xForwardedProto? })`

Get the request protocol.
If `x-forwarded-proto` header is set to "https", it will return "https". You can disable this behavior by setting `xForwardedProto` to `false`.
If protocol cannot be determined, it will default to "http".

### `getRequestURL(event, opts: { xForwardedHost?, xForwardedProto? })`

Generated the full incoming request URL using `getRequestProtocol`, `getRequestHost` and `event.path`.
If `xForwardedHost` is `true`, it will use the `x-forwarded-host` header if it exists.
If `xForwardedProto` is `false`, it will not use the `x-forwarded-proto` header.

### `getRouterParam(event, name, opts: { decode? })`

Get a matched route param by name.

### `getRouterParams(event, opts: { decode? })`

Get matched route params.
If `decode` option is `true`, it will decode the matched route params using `decodeURI`.

### `getValidatedQuery(event, validate)`

Get the query param from the request URL parsed with [unjs/ufo](https://ufo.unjs.io) and validated with validate function.

### `getValidatedRouterParams(event, validate, opts: { decode? })`

Get matched route params and validate with validate function.

### `isMethod(event, expected, allowHead?)`

Checks if the incoming request method is of the expected type.
If `allowHead` is `true`, it will allow `HEAD` requests to pass if the expected method is `GET`.

### `toWebRequest(event)`

Convert the H3Event to a WebRequest object.
**NOTE:** This function is not stable and might have edge cases that are not handled properly.

<!-- /automd -->

<!-- automd:jsdocs src="../../src/utils/fingerprint.ts" -->

### `getRequestFingerprint(event, opts)`

Get a unique fingerprint for the incoming request.

<!-- /automd -->

## Body utils
Expand Down
51 changes: 50 additions & 1 deletion docs/2.utils/2.reponse.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,54 +6,103 @@

### `appendHeader(event, name, value)`

Append a response header by name.

### `appendHeaders(event, headers)`

Append the response headers.

### `appendResponseHeader(event, name, value)`

Append a response header by name.

### `appendResponseHeaders(event, headers)`

Append the response headers.

### `clearResponseHeaders(event, headerNames?)`

Remove all response headers, or only those specified in the headerNames array.

### `defaultContentType(event, type?)`

Set the response status code and message.

### `getResponseHeader(event, name)`

Alias for `getResponseHeaders`.

### `getResponseHeaders(event)`

Get the response headers object.

### `getResponseStatus(event)`

Get the current response status code.

### `getResponseStatusText(event)`

Get the current response status message.

### `isStream(data)`

Checks if the data is a stream. (Node.js Readable Stream, React Pipeable Stream, or Web Stream)

### `isWebResponse(data)`

Checks if the data is a Response object.

### `removeResponseHeader(event, name)`

Remove a response header by name.

### `send(event, data?, type?)`

Directly send a response to the client.
**Note:** This function should be used only when you want to send a response directly without using the `h3` event. Normaly you can directly `return` a value inside event handlers.

### `sendNoContent(event, code?)`

Respond with an empty payload.<br> Note that calling this function will close the connection and no other data can be sent to the client afterwards.
Respond with an empty payload.<br>
Note that calling this function will close the connection and no other data can be sent to the client afterwards.

### `sendRedirect(event, location, code)`

Send a redirect response to the client.
It adds the `location` header to the response and sets the status code to 302 by default.
In the body, it sends a simple HTML page with a meta refresh tag to redirect the client in case the headers are ignored.

### `sendStream(event, stream)`

Send a stream response to the client.
Note: You can directly `return` a stream value inside event handlers alternatively which is recommended.

### `sendWebResponse(event, response)`

Send a Response object to the client.

### `setHeader(event, name, value)`

Set a response header by name.

### `setHeaders(event)`

Set the response headers.

### `setResponseHeader(event, name, value)`

Set a response header by name.

### `setResponseHeaders(event)`

Set the response headers.

### `setResponseStatus(event, code?, text?)`

Set the response status code and message.

### `writeEarlyHints(event, hints, cb)`

Write `HTTP/1.1 103 Early Hints` to the client.

<!-- /automd -->
42 changes: 35 additions & 7 deletions docs/2.utils/98.advanced.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,28 @@

### `clearSession(event, config)`

Clear the session data for the current request.

### `getSession(event, config)`

Get the session for the current request.

### `sealSession(event, config)`

Encrypt and sign the session data for the current request.

### `unsealSession(_event, config, sealed)`

Decrypt and verify the session data for the current request.

### `updateSession(event, config, update?)`

Update the session data for the current request.

### `useSession(event, config)`

Create a session manager for the current request.

<!-- /automd -->

## Cookie utils
Expand All @@ -40,10 +52,6 @@ Parse the request to get HTTP Cookie header string and returning an object of al

Set a cookie value by name.

### `splitCookiesString(cookiesString)`

Set-Cookie header field-values are sometimes comma joined in one string. This splits them without choking on commas that are within a single set-cookie field-value, such as in the Expires portion. This is uncommon, but explicitly allowed - see https://tools.ietf.org/html/rfc2616#section-4.2 Node.js does this for every header _except_ set-cookie - see https://github.com/nodejs/node/blob/d5e363b77ebaf1caf67cd7528224b651c86815c1/lib/_http_incoming.js#L128 Based on: https://github.com/google/j2objc/commit/16820fdbc8f76ca0c33472810ce0cb03d20efe25 Credits to: https://github.com/tomball for original and https://github.com/chrusart for JavaScript implementation

<!-- /automd -->

## Sanitize
Expand All @@ -52,8 +60,13 @@ Set-Cookie header field-values are sometimes comma joined in one string. This sp

### `sanitizeStatusCode(statusCode?, defaultStatusCode)`

Make sure the status code is a valid HTTP status code.

### `sanitizeStatusMessage(statusMessage)`

Make sure the status message is safe to use in a response.
Allowed characters: horizontal tabs, spaces or visible ascii characters: https://www.rfc-editor.org/rfc/rfc7230#section-3.1.2

<!-- /automd -->

## Route
Expand Down Expand Up @@ -82,12 +95,20 @@ Check request caching headers (`If-Modified-Since`) and add caching headers (Las

### `fetchWithEvent(event, req, init?, options?: { fetch: F })`

Make a fetch request with the event's context and headers.

### `getProxyRequestHeaders(event)`

Get the request headers object without headers known to cause issues when proxying.

### `proxyRequest(event, target, opts)`

Proxy the incoming request to a target URL.

### `sendProxy(event, target, opts)`

Make a proxy request to a target URL and send the response back to the client.

<!-- /automd -->

## CORS
Expand All @@ -96,17 +117,24 @@ Check request caching headers (`If-Modified-Since`) and add caching headers (Las

### `appendCorsHeaders(event, options)`

c8 ignore end
c8 ignore start
Append CORS headers to the response.

### `appendCorsPreflightHeaders(event, options)`

c8 ignore start
Append CORS preflight headers to the response.

### `handleCors(event, options)`

Handle CORS for the incoming request.
If the incoming request is a CORS preflight request, it will append the CORS preflight headers and send a 204 response.
If return value is `true`, the request is handled and no further action is needed.

### `isCorsOriginAllowed(origin, options)`

Check if the incoming request is a CORS request.

### `isPreflightRequest(event)`

Check if the incoming request is a CORS preflight request.

<!-- /automd -->
Binary file modified docs/bun.lockb
Binary file not shown.
2 changes: 1 addition & 1 deletion docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@
"dev": "undocs dev"
},
"devDependencies": {
"undocs": "^0.2.12"
"undocs": "^0.2.13"
}
}
3 changes: 3 additions & 0 deletions src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ export interface App {
use: AppUse;
}

/**
* Create a new H3 app instance.
*/
export function createApp(options: AppOptions = {}): App {
const stack: Stack = [];
const handler = createAppEventHandler(stack, options);
Expand Down
3 changes: 3 additions & 0 deletions src/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ export interface CreateRouterOptions {
preemptive?: boolean;
}

/**
* Create a new h3 router instance.
*/
export function createRouter(opts: CreateRouterOptions = {}): Router {
const _router = _createRouter<RouteNode>({});
const routes: Record<string, RouteNode> = {};
Expand Down
7 changes: 5 additions & 2 deletions src/utils/cookie.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,13 +79,16 @@ export function deleteCookie(
}

/**
* Set-Cookie header field-values are sometimes comma joined in one string. This splits them without choking on commas
* that are within a single set-cookie field-value, such as in the Expires portion.
* Set-Cookie header field-values are sometimes comma joined in one string.
*
* This splits them without choking on commas that are within a single set-cookie field-value, such as in the Expires portion.
* This is uncommon, but explicitly allowed - see https://tools.ietf.org/html/rfc2616#section-4.2
* Node.js does this for every header _except_ set-cookie - see https://github.com/nodejs/node/blob/d5e363b77ebaf1caf67cd7528224b651c86815c1/lib/_http_incoming.js#L128
* Based on: https://github.com/google/j2objc/commit/16820fdbc8f76ca0c33472810ce0cb03d20efe25
* Credits to: https://github.com/tomball for original and https://github.com/chrusart for JavaScript implementation
* @source https://github.com/nfriedly/set-cookie-parser/blob/3eab8b7d5d12c8ed87832532861c1a35520cf5b3/lib/set-cookie.js#L144
*
* @internal
*/
export function splitCookiesString(cookiesString: string | string[]): string[] {
if (Array.isArray(cookiesString)) {
Expand Down
7 changes: 7 additions & 0 deletions src/utils/cors/handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@ import {
} from "./utils";
import type { H3CorsOptions } from "./types";

/**
* Handle CORS for the incoming request.
*
* If the incoming request is a CORS preflight request, it will append the CORS preflight headers and send a 204 response.
*
* If return value is `true`, the request is handled and no further action is needed.
*/
export function handleCors(event: H3Event, options: H3CorsOptions): boolean {
const _options = resolveCorsOptions(options);
if (isPreflightRequest(event)) {
Expand Down

0 comments on commit c8aa150

Please sign in to comment.