Skip to content

Commit

Permalink
Add third parameter with response to trace and allow it to be asynchr…
Browse files Browse the repository at this point in the history
…onous (#53)
  • Loading branch information
diogob committed Aug 2, 2024
1 parent 3674738 commit 7af935b
Show file tree
Hide file tree
Showing 4 changed files with 13 additions and 4 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -408,8 +408,11 @@ await enhancedFetch("https://example.com/api/users/:role", {
// method: 'POST',
// body: '{"some":{"object":{"as":{"body":{}}}}}',
// }
// Response {}
```

The `trace` function can also return a `Promise<void>` in order to send traces to an external service or database.

## typedResponse

A type-safe wrapper around the `Response` object. It adds a `json` and `text` method that will parse the response with a given zod schema. If you don't provide a schema, it will return `unknown` instead of `any`, then you can also give it a generic to type cast the result.
Expand Down
2 changes: 2 additions & 0 deletions src/api.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ describe('enhancedFetch', () => {
method: 'POST',
body: `{"id":1,"name":{"first":"John","last":"Doe"}}`,
},
expect.any(Response),
)
})

Expand Down Expand Up @@ -358,6 +359,7 @@ describe('makeFetcher', () => {
body: `{"id":1,"name":{"first":"John","last":"Doe"}}`,
headers: new Headers(),
},
expect.any(Response),
)
})
})
Expand Down
6 changes: 3 additions & 3 deletions src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ function typedResponse(
* @param requestInit the requestInit to be passed to the fetch request. It is the same as the `RequestInit` type, but it also accepts a JSON-like `body` and an object-like `query` parameter.
* @param requestInit.body the body of the request. It will be automatically stringified so you can send a JSON-like object
* @param requestInit.query the query parameters to be added to the URL
* @param requestInit.trace a function that receives the URL and the requestInit and can be used to log the request
* @param requestInit.trace a function that receives the URL, the requestInit and a clone of the response in order to log or troubleshoot the request
* @returns a Response with typed json and text methods
* @example const response = await fetch("https://example.com/api/users");
* const users = await response.json(userSchema);
Expand All @@ -83,11 +83,11 @@ async function enhancedFetch<T extends string | URL>(
const body = ensureStringBody(reqInit.body)
const withParams = replaceURLParams<T>(url, reqInit.params ?? ({} as never))
const fullURL = addQueryToURL(withParams, query)

const enhancedReqInit = { ...reqInit, body }
trace?.(fullURL, enhancedReqInit)

const response = await fetch(fullURL, enhancedReqInit)

await trace?.(fullURL, enhancedReqInit, typedResponse(response.clone()))
return typedResponse(response)
}

Expand Down
6 changes: 5 additions & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,11 @@ type EnhancedRequestInit<T = string> = Omit<RequestInit, 'body' | 'method'> & {
body?: JSONValue | BodyInit | null
query?: SearchParams
params?: PathParams<T>
trace?: (...args: Parameters<typeof fetch>) => void
trace?: (
fullUrl: string | URL,
init: EnhancedRequestInit,
response: TypedResponse,
) => void | Promise<void>
}

type ServiceRequestInit<T = string> = Omit<EnhancedRequestInit<T>, 'method'>
Expand Down

0 comments on commit 7af935b

Please sign in to comment.