diff --git a/.changeset/init-ofetch.md b/.changeset/init-ofetch.md
new file mode 100644
index 0000000000..7311a09076
--- /dev/null
+++ b/.changeset/init-ofetch.md
@@ -0,0 +1,5 @@
+---
+"@hey-api/openapi-ts": patch
+---
+
+feat: add `ofetch` client available as `@hey-api/client-ofetch`
diff --git a/docs/.vitepress/config/en.ts b/docs/.vitepress/config/en.ts
index d3c9213ac6..89994a6cbb 100644
--- a/docs/.vitepress/config/en.ts
+++ b/docs/.vitepress/config/en.ts
@@ -103,6 +103,10 @@ export default defineConfig({
link: '/openapi-ts/clients/nuxt',
text: 'Nuxt',
},
+ {
+ link: '/openapi-ts/clients/ofetch',
+ text: 'OFetch',
+ },
{
link: '/openapi-ts/clients/effect',
text: 'Effect soon',
diff --git a/docs/openapi-ts/clients.md b/docs/openapi-ts/clients.md
index 2d6944a719..e267a60bed 100644
--- a/docs/openapi-ts/clients.md
+++ b/docs/openapi-ts/clients.md
@@ -30,6 +30,7 @@ Hey API natively supports the following clients.
- [Axios](/openapi-ts/clients/axios)
- [Next.js](/openapi-ts/clients/next-js)
- [Nuxt](/openapi-ts/clients/nuxt)
+- [OFetch](/openapi-ts/clients/ofetch)
- [Effect](/openapi-ts/clients/effect) Soon
- [Legacy](/openapi-ts/clients/legacy)
diff --git a/docs/openapi-ts/clients/angular.md b/docs/openapi-ts/clients/angular.md
index 87a2e22cec..13905848ba 100644
--- a/docs/openapi-ts/clients/angular.md
+++ b/docs/openapi-ts/clients/angular.md
@@ -231,9 +231,9 @@ const url = client.buildUrl({
console.log(url); // prints '/foo/1?bar=baz'
```
-## Custom `httpClient`
+## Custom Instance
-You can implement your own `httpClient`. This is useful if you need to extend the default `httpClient` methods with extra functionality, or replace it altogether.
+You can provide a custom `httpClient` instance. This is useful if you need to extend the default instance with extra functionality, or replace it altogether.
```js
import { client } from 'client/client.gen';
@@ -243,7 +243,7 @@ client.setConfig({
});
```
-You can use any of the approaches mentioned in [Configuration](#configuration), depending on how granular you want your custom client to be.
+You can use any of the approaches mentioned in [Configuration](#configuration), depending on how granular you want your custom instance to be.
## Plugins
diff --git a/docs/openapi-ts/clients/angular/v19.md b/docs/openapi-ts/clients/angular/v19.md
index b755acde40..235abafac0 100644
--- a/docs/openapi-ts/clients/angular/v19.md
+++ b/docs/openapi-ts/clients/angular/v19.md
@@ -231,9 +231,9 @@ const url = client.buildUrl({
console.log(url); // prints '/foo/1?bar=baz'
```
-## Custom `httpClient`
+## Custom Instance
-You can implement your own `httpClient`. This is useful if you need to extend the default `httpClient` methods with extra functionality, or replace it altogether.
+You can provide a custom `httpClient` instance. This is useful if you need to extend the default instance with extra functionality, or replace it altogether.
```js
import { client } from 'client/client.gen';
@@ -243,7 +243,7 @@ client.setConfig({
});
```
-You can use any of the approaches mentioned in [Configuration](#configuration), depending on how granular you want your custom client to be.
+You can use any of the approaches mentioned in [Configuration](#configuration), depending on how granular you want your custom instance to be.
## Plugins
diff --git a/docs/openapi-ts/clients/axios.md b/docs/openapi-ts/clients/axios.md
index b485ee1d84..1e2312228a 100644
--- a/docs/openapi-ts/clients/axios.md
+++ b/docs/openapi-ts/clients/axios.md
@@ -211,9 +211,9 @@ const url = client.buildUrl({
console.log(url); // prints '/foo/1?bar=baz'
```
-## Custom `axios`
+## Custom Instance
-You can implement your own `axios` instance. This is useful if you need to extend the default `axios` instance with extra functionality, or replace it altogether.
+You can provide a custom `axios` instance. This is useful if you need to extend the default instance with extra functionality, or replace it altogether.
```js
import axios from 'axios';
diff --git a/docs/openapi-ts/clients/fetch.md b/docs/openapi-ts/clients/fetch.md
index 9691d3fa4f..192791758b 100644
--- a/docs/openapi-ts/clients/fetch.md
+++ b/docs/openapi-ts/clients/fetch.md
@@ -146,27 +146,32 @@ const response = await getFoo({
## Interceptors
-Interceptors (middleware) can be used to modify requests before they're sent or responses before they're returned to your application. They can be added with `use`, removed with `eject`, and updated wth `update`. The `use` and `update` methods will return the id of the interceptor for use with `eject` and `update`. Fetch API does not have the interceptor functionality, so we implement our own. Below is an example request interceptor
+Interceptors (middleware) can be used to modify requests before they're sent or responses before they're returned to your application.
+
+They can be added with `use`, removed with `eject`, and updated wth `update`. The `use` and `update` methods will return the ID of the interceptor for use with `eject` and `update`. Fetch API does not have the interceptor functionality, so we implement our own.
+
+### Example: Request interceptor
::: code-group
```js [use]
import { client } from 'client/client.gen';
-// Supports async functions
+
async function myInterceptor(request) {
// do something
return request;
}
+
interceptorId = client.interceptors.request.use(myInterceptor);
```
```js [eject]
import { client } from 'client/client.gen';
-// eject interceptor by interceptor id
+// eject by ID
client.interceptors.request.eject(interceptorId);
-// eject interceptor by reference to interceptor function
+// eject by reference
client.interceptors.request.eject(myInterceptor);
```
@@ -177,36 +182,38 @@ async function myNewInterceptor(request) {
// do something
return request;
}
-// update interceptor by interceptor id
+
+// update by ID
client.interceptors.request.update(interceptorId, myNewInterceptor);
-// update interceptor by reference to interceptor function
+// update by reference
client.interceptors.request.update(myInterceptor, myNewInterceptor);
```
:::
-and an example response interceptor
+### Example: Response interceptor
::: code-group
```js [use]
import { client } from 'client/client.gen';
+
async function myInterceptor(response) {
// do something
return response;
}
-// Supports async functions
+
interceptorId = client.interceptors.response.use(myInterceptor);
```
```js [eject]
import { client } from 'client/client.gen';
-// eject interceptor by interceptor id
+// eject by ID
client.interceptors.response.eject(interceptorId);
-// eject interceptor by reference to interceptor function
+// eject by reference
client.interceptors.response.eject(myInterceptor);
```
@@ -217,17 +224,18 @@ async function myNewInterceptor(response) {
// do something
return response;
}
-// update interceptor by interceptor id
+
+// update by ID
client.interceptors.response.update(interceptorId, myNewInterceptor);
-// update interceptor by reference to interceptor function
+// update by reference
client.interceptors.response.update(myInterceptor, myNewInterceptor);
```
:::
::: tip
-To eject, you must provide the id or reference of the interceptor passed to `use()`, the id is the value returned by `use()` and `update()`.
+To eject, you must provide the ID or reference of the interceptor passed to `use()`, the ID is the value returned by `use()` and `update()`.
:::
## Auth
@@ -281,9 +289,9 @@ const url = client.buildUrl({
console.log(url); // prints '/foo/1?bar=baz'
```
-## Custom `fetch`
+## Custom Instance
-You can implement your own `fetch` method. This is useful if you need to extend the default `fetch` method with extra functionality, or replace it altogether.
+You can provide a custom `fetch` instance. This is useful if you need to extend the default instance with extra functionality, or replace it altogether.
```js
import { client } from 'client/client.gen';
@@ -295,7 +303,7 @@ client.setConfig({
});
```
-You can use any of the approaches mentioned in [Configuration](#configuration), depending on how granular you want your custom method to be.
+You can use any of the approaches mentioned in [Configuration](#configuration), depending on how granular you want your custom instance to be.
## API
diff --git a/docs/openapi-ts/clients/next-js.md b/docs/openapi-ts/clients/next-js.md
index f9013ad653..2ede4ffd28 100644
--- a/docs/openapi-ts/clients/next-js.md
+++ b/docs/openapi-ts/clients/next-js.md
@@ -130,27 +130,32 @@ const response = await getFoo({
## Interceptors
-Interceptors (middleware) can be used to modify requests before they're sent or responses before they're returned to your application. They can be added with `use`, removed with `eject`, and updated wth `update`. The `use` and `update` methods will return the id of the interceptor for use with `eject` and `update`. Fetch API does not have the interceptor functionality, so we implement our own. Below is an example request interceptor
+Interceptors (middleware) can be used to modify requests before they're sent or responses before they're returned to your application.
+
+They can be added with `use`, removed with `eject`, and updated wth `update`. The `use` and `update` methods will return the ID of the interceptor for use with `eject` and `update`. Fetch API does not have the interceptor functionality, so we implement our own.
+
+### Example: Request interceptor
::: code-group
```js [use]
import { client } from 'client/client.gen';
-// Supports async functions
+
async function myInterceptor(request) {
// do something
return request;
}
+
interceptorId = client.interceptors.request.use(myInterceptor);
```
```js [eject]
import { client } from 'client/client.gen';
-// eject interceptor by interceptor id
+// eject by ID
client.interceptors.request.eject(interceptorId);
-// eject interceptor by reference to interceptor function
+// eject by reference
client.interceptors.request.eject(myInterceptor);
```
@@ -161,36 +166,38 @@ async function myNewInterceptor(request) {
// do something
return request;
}
-// update interceptor by interceptor id
+
+// update by ID
client.interceptors.request.update(interceptorId, myNewInterceptor);
-// update interceptor by reference to interceptor function
+// update by reference
client.interceptors.request.update(myInterceptor, myNewInterceptor);
```
:::
-and an example response interceptor
+### Example: Response interceptor
::: code-group
```js [use]
import { client } from 'client/client.gen';
+
async function myInterceptor(response) {
// do something
return response;
}
-// Supports async functions
+
interceptorId = client.interceptors.response.use(myInterceptor);
```
```js [eject]
import { client } from 'client/client.gen';
-// eject interceptor by interceptor id
+// eject by ID
client.interceptors.response.eject(interceptorId);
-// eject interceptor by reference to interceptor function
+// eject by reference
client.interceptors.response.eject(myInterceptor);
```
@@ -201,17 +208,18 @@ async function myNewInterceptor(response) {
// do something
return response;
}
-// update interceptor by interceptor id
+
+// update by ID
client.interceptors.response.update(interceptorId, myNewInterceptor);
-// update interceptor by reference to interceptor function
+// update by reference
client.interceptors.response.update(myInterceptor, myNewInterceptor);
```
:::
::: tip
-To eject, you must provide the id or reference of the interceptor passed to `use()`, the id is the value returned by `use()` and `update()`.
+To eject, you must provide the ID or reference of the interceptor passed to `use()`, the ID is the value returned by `use()` and `update()`.
:::
## Auth
@@ -264,9 +272,9 @@ const url = client.buildUrl({
console.log(url); // prints '/foo/1?bar=baz'
```
-## Custom `fetch`
+## Custom Instance
-You can implement your own `fetch` method. This is useful if you need to extend the default `fetch` method with extra functionality, or replace it altogether.
+You can provide a custom `fetch` instance. This is useful if you need to extend the default instance with extra functionality, or replace it altogether.
```js
import { client } from 'client/client.gen';
@@ -278,7 +286,7 @@ client.setConfig({
});
```
-You can use any of the approaches mentioned in [Configuration](#configuration), depending on how granular you want your custom method to be.
+You can use any of the approaches mentioned in [Configuration](#configuration), depending on how granular you want your custom instance to be.
## API
diff --git a/docs/openapi-ts/clients/nuxt.md b/docs/openapi-ts/clients/nuxt.md
index 333914f493..21fe7c7236 100644
--- a/docs/openapi-ts/clients/nuxt.md
+++ b/docs/openapi-ts/clients/nuxt.md
@@ -243,9 +243,9 @@ const url = client.buildUrl({
console.log(url); // prints '/foo/1?bar=baz'
```
-## Custom `$fetch`
+## Custom Instance
-You can implement your own `$fetch` method. This is useful if you need to extend the default `$fetch` method with extra functionality, or replace it altogether.
+You can provide a custom `$fetch` instance. This is useful if you need to extend the default instance with extra functionality, or replace it altogether.
```js
import { client } from 'client/client.gen';
@@ -257,7 +257,7 @@ client.setConfig({
});
```
-You can use any of the approaches mentioned in [Configuration](#configuration), depending on how granular you want your custom method to be.
+You can use any of the approaches mentioned in [Configuration](#configuration), depending on how granular you want your custom instance to be.
## API
diff --git a/docs/openapi-ts/clients/ofetch.md b/docs/openapi-ts/clients/ofetch.md
new file mode 100644
index 0000000000..4798a0b1b0
--- /dev/null
+++ b/docs/openapi-ts/clients/ofetch.md
@@ -0,0 +1,341 @@
+---
+title: OFetch Client
+description: Generate a type-safe ofetch client from OpenAPI with the ofetch client for openapi-ts. Fully compatible with validators, transformers, and all core features.
+---
+
+# OFetch
+
+### About
+
+[`ofetch`](https://github.com/unjs/ofetch) is a better Fetch API that adds useful defaults and features such as automatic response parsing, request/response hooks, and it works in Node, browser, and workers.
+
+The `ofetch` client for Hey API generates a type-safe client from your OpenAPI spec, fully compatible with validators, transformers, and all core features.
+
+## Features
+
+- seamless integration with `@hey-api/openapi-ts` ecosystem
+- type-safe response data and errors
+- response data validation and transformation
+- access to the original request and response
+- granular request and response customization options
+- minimal learning curve thanks to extending the underlying technology
+- support bundling inside the generated output
+
+## Installation
+
+In your [configuration](/openapi-ts/get-started), add `@hey-api/client-ofetch` to your plugins and you'll be ready to generate client artifacts. :tada:
+
+::: code-group
+
+```js [config]
+export default {
+ input: 'hey-api/backend', // sign up at app.heyapi.dev
+ output: 'src/client',
+ plugins: ['@hey-api/client-ofetch'], // [!code ++]
+};
+```
+
+```sh [cli]
+npx @hey-api/openapi-ts \
+ -i hey-api/backend \
+ -o src/client \
+ -c @hey-api/client-ofetch # [!code ++]
+```
+
+:::
+
+## Configuration
+
+The `ofetch` client is built as a thin wrapper on top of `ofetch`, extending its functionality to work with Hey API. If you're already familiar with `ofetch`, configuring your client will feel like working directly with `ofetch`.
+
+When we installed the client above, it created a [`client.gen.ts`](/openapi-ts/output#client) file. You will most likely want to configure the exported `client` instance. There are two ways to do that.
+
+### `setConfig()`
+
+This is the simpler approach. You can call the `setConfig()` method at the beginning of your application or anytime you need to update the client configuration. You can pass any `ofetch` configuration option to `setConfig()`, and even your own [`ofetch`](#custom-ofetch) instance.
+
+```js
+import { client } from 'client/client.gen';
+
+client.setConfig({
+ baseUrl: 'https://example.com',
+});
+```
+
+The disadvantage of this approach is that your code may call the `client` instance before it's configured for the first time. Depending on your use case, you might need to use the second approach.
+
+### Runtime API
+
+Since `client.gen.ts` is a generated file, we can't directly modify it. Instead, we can tell our configuration to use a custom file implementing the Runtime API. We do that by specifying the `runtimeConfigPath` option.
+
+```js
+export default {
+ input: 'hey-api/backend', // sign up at app.heyapi.dev
+ output: 'src/client',
+ plugins: [
+ {
+ name: '@hey-api/client-ofetch',
+ runtimeConfigPath: './src/hey-api.ts', // [!code ++]
+ },
+ ],
+};
+```
+
+In our custom file, we need to export a `createClientConfig()` method. This function is a simple wrapper allowing us to override configuration values.
+
+::: code-group
+
+```ts [hey-api.ts]
+import type { CreateClientConfig } from './client/client.gen';
+
+export const createClientConfig: CreateClientConfig = (config) => ({
+ ...config,
+ baseUrl: 'https://example.com',
+});
+```
+
+:::
+
+With this approach, `client.gen.ts` will call `createClientConfig()` before initializing the `client` instance. If needed, you can still use `setConfig()` to update the client configuration later.
+
+### `createClient()`
+
+You can also create your own client instance. You can use it to manually send requests or point it to a different domain.
+
+```js
+import { createClient } from './client/client';
+
+const myClient = createClient({
+ baseUrl: 'https://example.com',
+});
+```
+
+You can also pass this instance to any SDK function through the `client` option. This will override the default instance from `client.gen.ts`.
+
+```js
+const response = await getFoo({
+ client: myClient,
+});
+```
+
+### SDKs
+
+Alternatively, you can pass the client configuration options to each SDK function. This is useful if you don't want to create a client instance for one-off use cases.
+
+```js
+const response = await getFoo({
+ baseUrl: 'https://example.com', // <-- override default configuration
+});
+```
+
+## Interceptors
+
+Interceptors (middleware) can be used to modify requests before they're sent or responses before they're returned to your application.
+
+The `ofetch` client supports two complementary options:
+
+- built-in Hey API interceptors exposed via `client.interceptors`
+- native `ofetch` hooks passed through config (e.g. `onRequest`)
+
+### Example: Request interceptor
+
+::: code-group
+
+```js [use]
+import { client } from 'client/client.gen';
+
+async function myInterceptor(request) {
+ // do something
+ return request;
+}
+
+interceptorId = client.interceptors.request.use(myInterceptor);
+```
+
+```js [eject]
+import { client } from 'client/client.gen';
+
+// eject by ID
+client.interceptors.request.eject(interceptorId);
+
+// eject by reference
+client.interceptors.request.eject(myInterceptor);
+```
+
+```js [update]
+import { client } from 'client/client.gen';
+
+async function myNewInterceptor(request) {
+ // do something
+ return request;
+}
+
+// update by ID
+client.interceptors.request.update(interceptorId, myNewInterceptor);
+
+// update by reference
+client.interceptors.request.update(myInterceptor, myNewInterceptor);
+```
+
+:::
+
+### Example: Response interceptor
+
+::: code-group
+
+```js [use]
+import { client } from 'client/client.gen';
+
+async function myInterceptor(response) {
+ // do something
+ return response;
+}
+
+interceptorId = client.interceptors.response.use(myInterceptor);
+```
+
+```js [eject]
+import { client } from 'client/client.gen';
+
+// eject by ID
+client.interceptors.response.eject(interceptorId);
+
+// eject by reference
+client.interceptors.response.eject(myInterceptor);
+```
+
+```js [update]
+import { client } from 'client/client.gen';
+
+async function myNewInterceptor(response) {
+ // do something
+ return response;
+}
+
+// update interceptor by interceptor ID
+client.interceptors.response.update(interceptorId, myNewInterceptor);
+
+// update interceptor by reference to interceptor function
+client.interceptors.response.update(myInterceptor, myNewInterceptor);
+```
+
+:::
+
+::: tip
+To eject, you must provide the ID or reference of the interceptor passed to `use()`, the ID is the value returned by `use()` and `update()`.
+:::
+
+### Example: `ofetch` hooks
+
+```js
+import { client } from 'client/client.gen';
+
+client.setConfig({
+ onRequest: ({ options }) => {
+ // mutate ofetch options (headers, query, etc.)
+ },
+ onResponse: ({ response }) => {
+ // inspect/transform the raw Response
+ },
+ onRequestError: (ctx) => {
+ // handle request errors
+ },
+ onResponseError: (ctx) => {
+ // handle response errors
+ },
+});
+```
+
+## Auth
+
+The SDKs include auth mechanisms for every endpoint. You will want to configure the `auth` field to pass the right token for each request. The `auth` field can be a string or a function returning a string representing the token. The returned value will be attached only to requests that require auth.
+
+```js
+import { client } from 'client/client.gen';
+
+client.setConfig({
+ auth: () => '', // [!code ++]
+ baseUrl: 'https://example.com',
+});
+```
+
+If you're not using SDKs or generating auth, using interceptors is a common approach to configuring auth for each request.
+
+```js
+import { client } from 'client/client.gen';
+
+client.interceptors.request.use((request, options) => {
+ request.headers.set('Authorization', 'Bearer '); // [!code ++]
+ return request;
+});
+```
+
+You can also use the `ofetch` hooks.
+
+```js
+import { client } from 'client/client.gen';
+
+client.setConfig({
+ onRequest: ({ options }) => {
+ options.headers.set('Authorization', 'Bearer '); // [!code ++]
+ },
+});
+```
+
+## Build URL
+
+If you need to access the compiled URL, you can use the `buildUrl()` method. It's loosely typed by default to accept almost any value; in practice, you will want to pass a type hint.
+
+```ts
+type FooData = {
+ path: {
+ fooId: number;
+ };
+ query?: {
+ bar?: string;
+ };
+ url: '/foo/{fooId}';
+};
+
+const url = client.buildUrl({
+ path: {
+ fooId: 1,
+ },
+ query: {
+ bar: 'baz',
+ },
+ url: '/foo/{fooId}',
+});
+console.log(url); // prints '/foo/1?bar=baz'
+```
+
+## Custom Instance
+
+You can provide a custom `ofetch` instance. This is useful if you need to extend the default instance with extra functionality, or replace it altogether.
+
+```js
+import { ofetch } from 'ofetch';
+import { client } from 'client/client.gen';
+
+const customOFetchInstance = ofetch.create({
+ onRequest: ({ options }) => {
+ // customize request
+ },
+ onResponse: ({ response }) => {
+ // customize response
+ },
+});
+
+client.setConfig({
+ ofetch: customOFetchInstance,
+});
+```
+
+You can use any of the approaches mentioned in [Configuration](#configuration), depending on how granular you want your custom instance to be.
+
+## API
+
+You can view the complete list of options in the [UserConfig](https://github.com/hey-api/openapi-ts/blob/main/packages/openapi-ts/src/plugins/@hey-api/client-ofetch/types.d.ts) interface.
+
+
+
diff --git a/docs/openapi-ts/plugins/pinia-colada.md b/docs/openapi-ts/plugins/pinia-colada.md
index a58f6341a7..5ec2a00cc3 100644
--- a/docs/openapi-ts/plugins/pinia-colada.md
+++ b/docs/openapi-ts/plugins/pinia-colada.md
@@ -48,6 +48,12 @@ export default {
};
```
+::: tip
+When using this plugin in a Nuxt app, prefer the [ofetch client](/openapi-ts/clients/ofetch) for universal compatibility.
+
+The [nuxt client](/openapi-ts/clients/nuxt) is tailored for working directly with Nuxt composables (`$fetch` / `useFetch` / `useAsyncData`) and is not intended as a universal HTTP client for libraries like `@pinia/colada`.
+:::
+
## Output
The Pinia Colada plugin will generate the following artifacts, depending on the input specification.
diff --git a/examples/openapi-ts-ofetch/env.d.ts b/examples/openapi-ts-ofetch/env.d.ts
new file mode 100644
index 0000000000..11f02fe2a0
--- /dev/null
+++ b/examples/openapi-ts-ofetch/env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/examples/openapi-ts-ofetch/index.html b/examples/openapi-ts-ofetch/index.html
new file mode 100644
index 0000000000..c904903436
--- /dev/null
+++ b/examples/openapi-ts-ofetch/index.html
@@ -0,0 +1,12 @@
+
+
+
+
+
+ Hey API — ofetch example
+
+
+
+
+
+
diff --git a/examples/openapi-ts-ofetch/openapi-ts.config.ts b/examples/openapi-ts-ofetch/openapi-ts.config.ts
new file mode 100644
index 0000000000..e0d23642cc
--- /dev/null
+++ b/examples/openapi-ts-ofetch/openapi-ts.config.ts
@@ -0,0 +1,20 @@
+import { defineConfig } from '@hey-api/openapi-ts';
+
+export default defineConfig({
+ input:
+ 'https://raw.githubusercontent.com/swagger-api/swagger-petstore/master/src/main/resources/openapi.yaml',
+ output: {
+ format: 'prettier',
+ lint: 'eslint',
+ path: './src/client',
+ },
+ plugins: [
+ '@hey-api/client-ofetch',
+ '@hey-api/schemas',
+ '@hey-api/sdk',
+ {
+ enums: 'javascript',
+ name: '@hey-api/typescript',
+ },
+ ],
+});
diff --git a/examples/openapi-ts-ofetch/package.json b/examples/openapi-ts-ofetch/package.json
new file mode 100644
index 0000000000..ba4006a6de
--- /dev/null
+++ b/examples/openapi-ts-ofetch/package.json
@@ -0,0 +1,45 @@
+{
+ "name": "@example/openapi-ts-ofetch",
+ "private": true,
+ "version": "0.0.1",
+ "type": "module",
+ "scripts": {
+ "build": "vite build",
+ "dev": "vite",
+ "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx --fix --ignore-path .gitignore",
+ "openapi-ts": "openapi-ts",
+ "preview": "vite preview",
+ "typecheck": "vue-tsc --build --force"
+ },
+ "dependencies": {
+ "ofetch": "1.4.1",
+ "vue": "3.5.13"
+ },
+ "devDependencies": {
+ "@config/vite-base": "workspace:*",
+ "@hey-api/openapi-ts": "workspace:*",
+ "@rushstack/eslint-patch": "1.10.5",
+ "@tsconfig/node20": "20.1.4",
+ "@types/jsdom": "21.1.7",
+ "@types/node": "22.10.5",
+ "@vitejs/plugin-vue": "5.2.1",
+ "@vitejs/plugin-vue-jsx": "4.1.1",
+ "@vue/eslint-config-prettier": "10.1.0",
+ "@vue/eslint-config-typescript": "14.2.0",
+ "@vue/test-utils": "2.4.6",
+ "@vue/tsconfig": "0.7.0",
+ "autoprefixer": "10.4.20",
+ "eslint": "9.17.0",
+ "eslint-plugin-vue": "9.32.0",
+ "jsdom": "23.0.0",
+ "npm-run-all2": "6.2.0",
+ "postcss": "8.4.41",
+ "prettier": "3.4.2",
+ "tailwindcss": "3.4.9",
+ "typescript": "5.8.3",
+ "vite": "7.1.2",
+ "vite-plugin-vue-devtools": "7.7.0",
+ "vitest": "3.1.1",
+ "vue-tsc": "2.2.0"
+ }
+}
diff --git a/examples/openapi-ts-ofetch/postcss.config.js b/examples/openapi-ts-ofetch/postcss.config.js
new file mode 100644
index 0000000000..9eef821c48
--- /dev/null
+++ b/examples/openapi-ts-ofetch/postcss.config.js
@@ -0,0 +1,6 @@
+export default {
+ plugins: {
+ autoprefixer: {},
+ tailwindcss: {},
+ },
+};
diff --git a/examples/openapi-ts-ofetch/src/App.vue b/examples/openapi-ts-ofetch/src/App.vue
new file mode 100644
index 0000000000..d48b4c2018
--- /dev/null
+++ b/examples/openapi-ts-ofetch/src/App.vue
@@ -0,0 +1,190 @@
+
+
+
+