Skip to content

Commit

Permalink
feat(edge): adds json() response helper (vercel#9081)
Browse files Browse the repository at this point in the history
### 🔖 What's in there?

Because Typescript's `libdom` does not have [`static Response.json()`](microsoft/TypeScript-DOM-lib-generator#1444) (which modern browsers and edge runtimes are supporting), Typescript users can't use easily use it.

This helper fills the gap.

### 🧪 How to test?

It's covered with unit tests
  • Loading branch information
feugy authored Dec 15, 2022
1 parent 4484c13 commit 61e588c
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 0 deletions.
44 changes: 44 additions & 0 deletions packages/edge/docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

- [geolocation](README.md#geolocation)
- [ipAddress](README.md#ipaddress)
- [json](README.md#json)
- [next](README.md#next)
- [rewrite](README.md#rewrite)

Expand Down Expand Up @@ -169,6 +170,49 @@ Returns the IP address of the request from the headers.

---

### json

**json**(`data`, `init?`): `Response`

Builds a response object from a serializable JavaScript object:

- sets the 'Content-Type' response header to 'application/json'
- sets the response body from provided data

**`See`**

[https://fetch.spec.whatwg.org/#dom-response-json](https://fetch.spec.whatwg.org/#dom-response-json)

**`Example`**

<caption>Building a JSON response</caption>

```ts
import { json } from '@vercel/edge';

const response = json(
{ notification: { success: true, content: 'worked' } },
{ headers: { 'x-custom': '1' } }
);
```

#### Parameters

| Name | Type | Description |
| :------ | :------------- | :------------------------------------------------------ |
| `data` | `any` | serialized data |
| `init?` | `ResponseInit` | optional custom response status, statusText and headers |

#### Returns

`Response`

#### Defined in

[src/response.ts:19](https://github.com/vercel/vercel/blob/main/packages/edge/src/response.ts#L19)

---

### next

**next**(`init?`): `Response`
Expand Down
1 change: 1 addition & 0 deletions packages/edge/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ export * from './middleware-helpers';

export type { Geo } from './edge-headers';
export * from './edge-headers';
export * from './response';
22 changes: 22 additions & 0 deletions packages/edge/src/response.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/**
* Builds a response object from a serializable JavaScript object:
* - sets the 'Content-Type' response header to 'application/json'
* - sets the response body from provided data
*
* @see {@link https://fetch.spec.whatwg.org/#dom-response-json}
* @param data serialized data
* @param init optional custom response status, statusText and headers
*
* @example
* <caption>Building a JSON response</caption>
*
* ```ts
* import { json } from '@vercel/edge';
*
* const response = json({ notification: { success: true, content: 'worked' } }, { headers: {'x-custom': '1' }})
* ```
*/
export function json(data: any, init?: ResponseInit): Response {
// @ts-expect-error This is not in lib/dom right now, and we can't augment it.
return Response.json(data, init);
}
34 changes: 34 additions & 0 deletions packages/edge/test/response.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/**
* @jest-environment @edge-runtime/jest-environment
*/

import { json } from '../src/response';

describe('json', () => {
it('returns a response with JSON content', async () => {
const content = { foo: 'bar' };
const response = json(content);
expect(response.headers.get('content-type')).toEqual('application/json');
expect(await response.json()).toEqual(content);
});

it('can set response init', async () => {
const content = { bar: 'baz' };
const status = 201;
const statusText = 'it is in';
const customHeader = 'x-custom';
const customHeaderValue = '1';
const response = json(content, {
status,
statusText,
headers: { [customHeader]: customHeaderValue },
});
expect(response).toMatchObject({
status,
statusText,
});
expect(response.headers.get('content-type')).toEqual('application/json');
expect(response.headers.get(customHeader)).toEqual(customHeaderValue);
expect(await response.json()).toEqual(content);
});
});

0 comments on commit 61e588c

Please sign in to comment.