Skip to content

openapi-typescript@7, [email protected] 🎉 #1706

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jun 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .nvm

This file was deleted.

1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
22
2 changes: 1 addition & 1 deletion biome.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"$schema": "https://biomejs.dev/schemas/1.7.0/schema.json",
"$schema": "https://biomejs.dev/schemas/1.8.1/schema.json",
"organizeImports": {
"enabled": false
},
Expand Down
8 changes: 1 addition & 7 deletions docs/introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,6 @@ description: Quickstart

<img src="/assets/openapi-ts.svg" alt="openapi-typescript" width="200" height="40" />

::: warning

The 7.x docs are for a beta release that’s not production-ready yet. See the [6.x docs](/6.x/introduction) for the stable version.

:::

openapi-typescript turns [OpenAPI 3.0 & 3.1](https://spec.openapis.org/oas/latest.html) schemas into TypeScript quickly using Node.js. No Java/node-gyp/running OpenAPI servers necessary.

The code is [MIT-licensed](https://github.com/openapi-ts/openapi-typescript/blob/main/packages/openapi-typescript/LICENSE") and free for use.
Expand Down Expand Up @@ -39,7 +33,7 @@ _Note: OpenAPI 2.x is supported with versions `5.x` and previous_
This library requires the latest version of [Node.js](https://nodejs.org) installed (20.x or higher recommended). With that present, run the following in your project:

```bash
npm i -D openapi-typescript@next typescript
npm i -D openapi-typescript typescript
```

And in your `tsconfig.json`, to load the types properly:
Expand Down
2 changes: 1 addition & 1 deletion docs/node.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ The Node API may be useful if dealing with dynamically-created schemas, or you
## Setup

```bash
npm i --save-dev openapi-typescript@next typescript
npm i --save-dev openapi-typescript typescript
```

::: tip Recommended
Expand Down
71 changes: 19 additions & 52 deletions docs/openapi-fetch/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,12 +165,12 @@ import createClient from "openapi-fetch";
import type { paths } from "./my-openapi-3-schema"; // generated by openapi-typescript

const myMiddleware: Middleware = {
async onRequest(req, options) {
async onRequest({ request, options }) {
// set "foo" header
req.headers.set("foo", "bar");
return req;
request.headers.set("foo", "bar");
return request;
},
async onResponse(res, options) {
async onResponse({ request, response, options }) {
const { body, ...resOptions } = res;
// change status of response
return new Response(body, { ...resOptions, status: 200 });
Expand All @@ -183,60 +183,27 @@ const client = createClient<paths>({ baseUrl: "https://myapi.dev/v1/" });
client.use(myMiddleware);
```

### onRequest
### API

```ts
onRequest(req, options) {
// …
}
```

`onRequest()` takes 2 params:

| Name | Type | Description |
| :-------- | :-----------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `req` | `MiddlewareRequest` | A standard [Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) with `schemaPath` (OpenAPI pathname) and `params` ([params](/openapi-fetch/api#fetch-options) object) |
| `options` | `MergedOptions` | Combination of [createClient](/openapi-fetch/api#create-client) options + [fetch overrides](/openapi-fetch/api#fetch-options) |
#### Parameters

And it expects either:
Each middleware callback receives the following `options` object with the following:

- **If modifying the request:** A [Request](https://developer.mozilla.org/en-US/docs/Web/API/Request)
- **If not modifying:** `undefined` (void)
| Name | Type | Description |
| :----------- | :-------------- | :------------------------------------------------------------------------------------------ |
| `request` | `Request` | The current `Request` to be sent to the endpoint. |
| `response` | `Response` | The `Response` returned from the endpoint (note: this will be `undefined` for `onRequest`). |
| `schemaPath` | `string` | The original OpenAPI path called (e.g. `/users/{user_id}`) |
| `params` | `Object` | The original `params` object passed to `GET()` / `POST()` / etc. |
| `id` | `string` | A random, unique ID for this request. |
| `options` | `ClientOptions` | The readonly options passed to `createClient()`. |

### onResponse

```ts
onResponse(res, options, req) {
// …
}
```
#### Response

`onResponse()` also takes 3 params:
| Name | Type | Description |
| :-------- | :-----------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `req` | `Response` | A standard [Response](https://developer.mozilla.org/en-US/docs/Web/API/Response). |
| `options` | `MergedOptions` | Combination of [createClient](/openapi-fetch/api#create-client) options + [fetch overrides](/openapi-fetch/api#fetch-options) |
| `req` | `MiddlewareRequest` | A standard [Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) with `schemaPath` (OpenAPI pathname) and `params` ([params](/openapi-fetch/api#fetch-options) object) |

And it expects either:

- **If modifying the response:** A [Response](https://developer.mozilla.org/en-US/docs/Web/API/Response)
- **If not modifying:** `undefined` (void)

### Skipping

If you want to skip the middleware under certain conditions, just `return` as early as possible:

```ts
onRequest(req) {
if (req.schemaPath !== "/projects/{project_id}") {
return undefined;
}
// …
}
```
Each middleware callback can return:

This will leave the request/response unmodified, and pass things off to the next middleware handler (if any). There’s no internal callback or observer library needed.
- **onRequest**: Either a `Request` to modify the request, or `undefined` to leave it untouched (skip)
- **onResponse** Either a `Response` to modify the response, or `undefined` to leave it untouched (skip)

### Ejecting middleware

Expand Down
6 changes: 0 additions & 6 deletions docs/openapi-fetch/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,6 @@ Notice there are no generics, and no manual typing. Your endpoint’s request an

## Setup

::: warning

openapi-fetch currently requires [email protected] (latest). An upcoming breaking release will support [email protected].

:::

Install this library along with [openapi-typescript](/introduction):

```bash
Expand Down
44 changes: 21 additions & 23 deletions docs/openapi-fetch/middleware-auth.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@ import createClient from "openapi-fetch";
import type { paths } from "./my-openapi-3-schema"; // generated by openapi-typescript

const myMiddleware: Middleware = {
async onRequest(req, options) {
async onRequest({ request, options }) {
// set "foo" header
req.headers.set("foo", "bar");
return req;
request.headers.set("foo", "bar");
return request;
},
async onResponse(res, options) {
const { body, ...resOptions } = res;
async onResponse({ request, response, options }) {
const { body, ...resOptions } = response;
// change status of response
return new Response(body, { ...resOptions, status: 200 });
},
Expand All @@ -48,8 +48,8 @@ The order in which middleware are registered matters. For requests, `onRequest()
If you want to skip the middleware under certain conditions, just `return` as early as possible:

```ts
onRequest(req) {
if (req.schemaPath !== "/projects/{project_id}") {
onRequest({ schemaPath }) {
if (schemaPath !== "/projects/{project_id}") {
return undefined;
}
// …
Expand All @@ -63,9 +63,9 @@ This will leave the request/response unmodified, and pass things off to the next
Middleware can also be used to throw an error that `fetch()` wouldn’t normally, useful in libraries like [TanStack Query](https://tanstack.com/query/latest):

```ts
onResponse(res) {
if (res.error) {
throw new Error(res.error.message);
onResponse({ response }) {
if (response.error) {
throw new Error(response.error.message);
}
}
```
Expand Down Expand Up @@ -98,12 +98,10 @@ By default, `openapi-fetch` will **NOT** arbitrarily clone requests/responses fo
<!-- prettier-ignore -->
```ts
const myMiddleware: Middleware = {
onResponse(res) {
if (res) {
const data = await res.json(); // [!code --]
const data = await res.clone().json(); // [!code ++]
return undefined;
}
onResponse({ response }) {
const data = await response.json(); // [!code --]
const data = await response.clone().json(); // [!code ++]
return undefined;
},
};
```
Expand All @@ -125,7 +123,7 @@ import type { paths } from "./my-openapi-3-schema";
let accessToken: string | undefined = undefined;

const authMiddleware: Middleware = {
async onRequest(req) {
async onRequest({ request }) {
// fetch token, if it doesn’t exist
if (!accessToken) {
const authRes = await someAuthFunc();
Expand All @@ -139,8 +137,8 @@ const authMiddleware: Middleware = {
// (optional) add logic here to refresh token when it expires

// add Authorization header to every request
req.headers.set("Authorization", `Bearer ${accessToken}`);
return req;
request.headers.set("Authorization", `Bearer ${accessToken}`);
return request;
},
};

Expand All @@ -162,14 +160,14 @@ If authorization isn’t needed for certain routes, you could also handle that w
const UNPROTECTED_ROUTES = ["/v1/login", "/v1/logout", "/v1/public/"];

const authMiddleware = {
onRequest(req) {
if (UNPROTECTED_ROUTES.some((pathname) => req.url.startsWith(pathname))) {
onRequest({ url, request }) {
if (UNPROTECTED_ROUTES.some((pathname) => url.startsWith(pathname))) {
return undefined; // don’t modify request for certain paths
}

// for all other paths, set Authorization header as expected
req.headers.set("Authorization", `Bearer ${accessToken}`);
return req;
request.headers.set("Authorization", `Bearer ${accessToken}`);
return request;
},
};
```
Expand Down
2 changes: 1 addition & 1 deletion docs/zh/introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ _注意:OpenAPI 2.x 在版本 `5.x` 及更早版本中受支持_
此库需要安装最新版本的 [Node.js](https://nodejs.org)(建议使用 20.x 或更高版本)。安装完成后,在项目中运行以下命令:

```bash
npm i -D openapi-typescript@next typescript
npm i -D openapi-typescript typescript
```

::: tip 强烈推荐
Expand Down
2 changes: 1 addition & 1 deletion docs/zh/node.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Node.js API 对于处理动态创建的模式或在较大应用程序上下文
## 安装

```bash
npm i --save-dev openapi-typescript@next typescript
npm i --save-dev openapi-typescript typescript
```

::: tip 推荐
Expand Down
11 changes: 11 additions & 0 deletions packages/openapi-fetch/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
# openapi-fetch

## 0.10.0

### Minor Changes

- ⚠️ **Breaking Change**: `openapi-typescript@7` is needed to work. You’ll get type errors with `openapi-typescript@6` and below.
- ⚠️ **Breaking Change**: The Middleware API has changed to be an object rather than `(request, options)` or `(response, options)`. [See Middleware docs](https://openapi-ts.dev/openapi-fetch/middleware-auth) for updated API.
- ⚠️ **Breaking Change**: The `Content-Type` header is no longer sent by default if a body payload is attached.
- ⚠️ **Breaking Change**: The `customFetch` type now calls `fetch(input: string, init: RequestInit)` and the types have been updated, rather than `fetch(input: Request)` introduced in `0.9.0`.

- Added `id` to middleware handlers that create a unique ID per-fetch

## 0.9.8

### Patch Changes
Expand Down
12 changes: 11 additions & 1 deletion packages/openapi-fetch/biome.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,18 @@
{
"$schema": "https://biomejs.dev/schemas/1.7.0/schema.json",
"$schema": "https://biomejs.dev/schemas/1.8.1/schema.json",
"extends": ["../../biome.json"],
"files": {
"include": ["./src/", "./test/"],
"ignore": ["**/fixtures/**/*"]
},
"linter": {
"rules": {
"complexity": {
"noBannedTypes": "off"
},
"suspicious": {
"noConfusingVoidType": "off"
}
}
}
}
2 changes: 1 addition & 1 deletion packages/openapi-fetch/examples/nextjs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"react-dom": "18.3.1"
},
"devDependencies": {
"@types/node": "20.12.12",
"@types/node": "20.14.6",
"@types/react": "18.3.1",
"@types/react-dom": "18.3.0",
"openapi-typescript": "workspace:^",
Expand Down
2 changes: 1 addition & 1 deletion packages/openapi-fetch/examples/vue-3/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
},
"devDependencies": {
"@tsconfig/node20": "^20.1.4",
"@types/node": "^20.12.12",
"@types/node": "^20.14.6",
"@vitejs/plugin-vue": "^5.0.4",
"@vue/tsconfig": "^0.5.1",
"openapi-typescript": "workspace:^",
Expand Down
9 changes: 5 additions & 4 deletions packages/openapi-fetch/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,23 +54,24 @@
"build:cjs": "esbuild --bundle src/index.js --format=cjs --outfile=dist/cjs/index.cjs && cp dist/index.d.ts dist/cjs/index.d.cts",
"format": "biome format . --write",
"lint": "biome check .",
"generate-types": "node ./scripts/generate-types.js",
"generate-types": "openapi-typescript test/fixtures/api.yaml -o test/fixtures/api.d.ts",
"pretest": "pnpm run generate-types",
"test": "pnpm run \"/^test:/\"",
"test:js": "vitest run",
"test:ts": "tsc --noEmit",
"version": "pnpm run prepare && pnpm run build"
},
"dependencies": {
"nanoid": "^5.0.7",
"openapi-typescript-helpers": "workspace:^"
},
"devDependencies": {
"axios": "^1.6.8",
"axios": "^1.7.2",
"del-cli": "^5.1.0",
"esbuild": "^0.20.2",
"execa": "^8.0.1",
"msw": "^2.3.0",
"openapi-typescript": "^6.x",
"msw": "^2.3.1",
"openapi-typescript": "workspace:^",
"openapi-typescript-codegen": "^0.25.0",
"openapi-typescript-fetch": "^2.0.0",
"superagent": "^9.0.2",
Expand Down
21 changes: 0 additions & 21 deletions packages/openapi-fetch/scripts/generate-types.js

This file was deleted.

Loading
Loading