Skip to content

Commit

Permalink
feat!: overhaul internal design (#783)
Browse files Browse the repository at this point in the history
  • Loading branch information
pi0 authored Jun 24, 2024
1 parent ed61d5a commit 5a4e7f1
Show file tree
Hide file tree
Showing 108 changed files with 6,767 additions and 4,670 deletions.
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ lib
.nuxt
.output
docs/**/*.md
src/types/_headers.ts
19 changes: 19 additions & 0 deletions build.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { defineBuildConfig } from "unbuild";

export default defineBuildConfig({
declaration: true,
rollup: {
emitCJS: false,
output: {
chunkFileNames: "_shared.js",
},
esbuild: {
target: "ES2020",
tsconfigRaw: {
compilerOptions: {
useDefineForClassFields: false,
},
},
},
},
});
81 changes: 19 additions & 62 deletions docs/2.utils/1.request.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,32 +25,6 @@ export default defineEventHandler((event) => {
});
```

### `getHeader(event, name)`

Get a request header by name.

**Example:**

```ts
export default defineEventHandler((event) => {
const contentType = getRequestHeader(event, "content-type"); // "application/json"
});
```

### `getHeaders(event)`

Get the request headers object.

Array headers are joined with a comma.

**Example:**

```ts
export default defineEventHandler((event) => {
const headers = getRequestHeaders(event); // { "content-type": "application/json", "x-custom-header": "value" }
});
```

### `getQuery(event)`

Get query the params object from the request URL parsed with [unjs/ufo](https://ufo.unjs.io).
Expand Down Expand Up @@ -261,12 +235,6 @@ export default defineEventHandler((event) => {
});
```

### `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" -->
Expand All @@ -281,82 +249,71 @@ Get a unique fingerprint for the incoming request.

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

### `getRequestWebStream(event)`
### `getBodyStream(event)`

Captures a stream from a request.

### `readBody(event, options: { strict? })`
### `readFormDataBody(event)`

Reads request body and tries to safely parse using [destr](https://github.com/unjs/destr).
Constructs a FormData object from an event, after converting it to a a web request.

**Example:**

```ts
export default defineEventHandler(async (event) => {
const body = await readBody(event);
const formData = await readFormDataBody(event);
const email = formData.get("email");
const password = formData.get("password");
});
```

### `readFormData(event)`
### `readJSONBody(event)`

Constructs a FormData object from an event, after converting it to a a web request.
Reads request body and tries to parse using JSON.parse or URLSearchParams.

**Example:**

```ts
export default defineEventHandler(async (event) => {
const formData = await readFormData(event);
const email = formData.get("email");
const password = formData.get("password");
const body = await readAndParseBody(event);
});
```

### `readMultipartFormData(event)`
### `readRawBody(event)`

Tries to read and parse the body of a an H3Event as multipart form.
Reads body of the request and returns an Uint8Array of the raw body.

**Example:**

```ts
export default defineEventHandler(async (event) => {
const formData = await readMultipartFormData(event);
// The result could look like:
// [
// {
// "data": "other",
// "name": "baz",
// },
// {
// "data": "something",
// "name": "some-other-data",
// },
// ];
const body = await readRawBody(event);
});
```

### `readRawBody(event, encoding)`
### `readTextBody(event)`

Reads body of the request and returns encoded raw string (default), or `Buffer` if encoding is falsy.
Reads body of the request and returns an string (utf-8) of the raw body.

**Example:**

```ts
export default defineEventHandler(async (event) => {
const body = await readRawBody(event, "utf-8");
const body = await readTextBody(event);
});
```

### `readValidatedBody(event, validate)`
### `readValidatedJSONBody(event, validate)`

Tries to read the request body via `readBody`, then uses the provided validation function and either throws a validation error or returns the result.
Tries to read the request body via `readJSONBody`, then uses the provided validation function and either throws a validation error or returns the result.

You can use a simple function to validate the body or use a library like `zod` to define a schema.

**Example:**

```ts
export default defineEventHandler(async (event) => {
const body = await readValidatedBody(event, (body) => {
const body = await readValidatedJSONBody(event, (body) => {
return typeof body === "object" && body !== null;
});
});
Expand All @@ -368,7 +325,7 @@ export default defineEventHandler(async (event) => {
import { z } from "zod";
export default defineEventHandler(async (event) => {
const objectSchema = z.object();
const body = await readValidatedBody(event, objectSchema.safeParse);
const body = await readValidatedJSONBody(event, objectSchema.safeParse);
});
```

Expand Down
88 changes: 2 additions & 86 deletions docs/2.utils/2.response.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,33 +8,6 @@ icon: material-symbols-light:output
<!-- automd:jsdocs src="../../src/utils/response.ts" -->

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

Append a response header by name.

**Example:**

```ts
export default defineEventHandler((event) => {
appendResponseHeader(event, "content-type", "text/html");
});
```

### `appendHeaders(event, headers)`

Append the response headers.

**Example:**

```ts
export default defineEventHandler((event) => {
appendResponseHeaders(event, {
"content-type": "text/html",
"cache-control": "no-cache",
});
});
```

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

Append a response header by name.
Expand Down Expand Up @@ -80,16 +53,6 @@ Set the response status code and message.

### `getResponseHeader(event, name)`

Alias for `getResponseHeaders`.

**Example:**

```ts
export default defineEventHandler((event) => {
const contentType = getResponseHeader(event, "content-type"); // Get the response content-type header
});
```

### `getResponseHeaders(event)`

Get the response headers object.
Expand Down Expand Up @@ -128,14 +91,6 @@ export default defineEventHandler((event) => {
});
```

### `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.
Expand All @@ -148,12 +103,6 @@ export default defineEventHandler((event) => {
});
```

### `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. Normally you can directly `return` a value inside event handlers.

### `sendIterable(event, iterable)`

Iterate a source of chunks and send back each chunk in order. Supports mixing async work together with emitting chunks.
Expand Down Expand Up @@ -232,42 +181,9 @@ export default defineEventHandler((event) => {
});
```

### `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.

**Example:**

```ts
export default defineEventHandler((event) => {
setResponseHeader(event, "content-type", "text/html");
});
```

### `setHeaders(event, headers)`

Set the response headers.

**Example:**

```ts
export default defineEventHandler((event) => {
setResponseHeaders(event, {
"content-type": "text/html",
"cache-control": "no-cache",
});
});
```
Send a Web besponse object to the client.

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

Expand Down Expand Up @@ -309,7 +225,7 @@ export default defineEventHandler((event) => {
});
```

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

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

Expand Down
36 changes: 30 additions & 6 deletions docs/2.utils/98.advanced.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,36 @@ Get a cookie value by name.

Parse the request to get HTTP Cookie header string and returning an object of all cookie name-value pairs.

### `setCookie(event, name, value, serializeOptions?)`
### `setCookie(event, name, value, options?)`

Set a cookie value by name.

<!-- /automd -->

## Fingerprint utils

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

### `getRequestFingerprint(event, opts)`

Get a unique fingerprint for the incoming request.

<!-- /automd -->

## WebSocket utils

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

### `defineWebSocket(hooks)`

Define WebSocket hooks.

### `defineWebSocketHandler(hooks)`

Define WebSocket event handler.

<!-- /automd -->

## Sanitize

<!-- automd:jsdocs src="../../src/utils/sanitize.ts" -->
Expand All @@ -74,9 +98,9 @@ Allowed characters: horizontal tabs, spaces or visible ascii characters: https:/

<!-- /automd -->

## Route
## Base

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

### `useBase(base, handler)`

Expand Down Expand Up @@ -133,7 +157,7 @@ Make a proxy request to a target URL and send the response back to the client.

## CORS

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

### `appendCorsHeaders(event, options)`

Expand Down Expand Up @@ -185,7 +209,7 @@ Check if the incoming request is a CORS preflight request.

## Server Sent Events (SSE)

<!-- automd:jsdocs src="../../src/utils/sse/index.ts" -->
<!-- automd:jsdocs src="../../src/utils/event-stream.ts" -->

### `createEventStream(event, opts?)`

Expand All @@ -196,7 +220,7 @@ Initialize an EventStream instance for creating [server sent events](https://dev
```ts
import { createEventStream, sendEventStream } from "h3";

eventHandler((event) => {
defineEventHandler((event) => {
const eventStream = createEventStream(event);

// Send a message every second
Expand Down
Loading

0 comments on commit 5a4e7f1

Please sign in to comment.