fork of hey-api/openapi-ts because I need some additional things

chore: update Angular docs

Lubos 70a28abb 937a874b

+1288 -436
+8 -4
docs/.vitepress/config/en.ts
··· 95 95 text: 'Fetch API', 96 96 }, 97 97 { 98 + link: '/openapi-ts/clients/angular', 99 + text: 'Angular', 100 + }, 101 + { 98 102 link: '/openapi-ts/clients/axios', 99 103 text: 'Axios', 100 104 }, ··· 105 109 { 106 110 link: '/openapi-ts/clients/nuxt', 107 111 text: 'Nuxt', 108 - }, 109 - { 110 - link: '/openapi-ts/clients/angular', 111 - text: 'Angular', 112 112 }, 113 113 { 114 114 link: '/openapi-ts/clients/effect', ··· 218 218 { 219 219 collapsed: true, 220 220 items: [ 221 + { 222 + link: '/openapi-ts/plugins/angular', 223 + text: 'Angular', 224 + }, 221 225 { 222 226 link: '/openapi-ts/plugins/fastify', 223 227 text: 'Fastify',
+8
docs/.vitepress/config/index.ts
··· 1 + import path from 'node:path'; 2 + 1 3 import { defineConfig } from 'vitepress'; 2 4 3 5 import en from './en'; ··· 13 15 ...shared.vite, 14 16 resolve: { 15 17 ...shared.vite?.resolve, 18 + alias: { 19 + ...shared.vite?.resolve?.alias, 20 + '@components': path.resolve(__dirname, '..', 'theme', 'components'), 21 + '@data': path.resolve(__dirname, '..', '..', 'data'), 22 + '@versions': path.resolve(__dirname, '..', 'theme', 'versions'), 23 + }, 16 24 preserveSymlinks: true, 17 25 }, 18 26 },
+1 -12
docs/.vitepress/theme/index.ts
··· 5 5 // custom CSS must be imported after default theme to correctly apply styles 6 6 import './custom.css'; 7 7 8 - import AuthorsList from './components/AuthorsList.vue'; 9 - import FeatureStatus from './components/FeatureStatus.vue'; 10 - import Heading from './components/Heading.vue'; 11 - import VersionLabel from './components/VersionLabel.vue'; 12 - import VersionSwitcher from './components/VersionSwitcher.vue'; 13 8 import Layout from './Layout.vue'; 14 9 15 10 export default { 16 11 Layout, 17 - enhanceApp: ({ app }) => { 18 - app.component('AuthorsList', AuthorsList); 19 - app.component('FeatureStatus', FeatureStatus); 20 - app.component('Heading', Heading); 21 - app.component('VersionLabel', VersionLabel); 22 - app.component('VersionSwitcher', VersionSwitcher); 23 - }, 12 + enhanceApp: () => {}, 24 13 extends: DefaultTheme, 25 14 } satisfies Theme;
+20
docs/.vitepress/theme/versions/AngularVersionSwitcher.vue
··· 1 + <script setup lang="ts"> 2 + import VersionSwitcher from '@components/VersionSwitcher.vue'; 3 + 4 + const versions = [ 5 + { 6 + label: 'Angular 20', 7 + short: 'v20', 8 + value: 'v20', 9 + }, 10 + { 11 + label: 'Angular 19', 12 + short: 'v19', 13 + value: 'v19', 14 + }, 15 + ]; 16 + </script> 17 + 18 + <template> 19 + <VersionSwitcher :values="versions" default="v20" /> 20 + </template>
+14
docs/data/people.ts
··· 1 + type Person = { 2 + github: string; 3 + name: string; 4 + }; 5 + 6 + export const jacobCohen: Person = { 7 + github: 'https://github.com/jacobinu', 8 + name: 'Jacob Cohen', 9 + }; 10 + 11 + export const maxScopp: Person = { 12 + github: 'https://github.com/max-scopp', 13 + name: 'Max Scopp', 14 + };
+1 -1
docs/openapi-ts/clients.md
··· 26 26 Hey API natively supports the following clients. 27 27 28 28 - [Fetch API](/openapi-ts/clients/fetch) 29 + - [Angular](/openapi-ts/clients/angular) 29 30 - [Axios](/openapi-ts/clients/axios) 30 31 - [Next.js](/openapi-ts/clients/next-js) 31 32 - [Nuxt](/openapi-ts/clients/nuxt) 32 - - [Angular](/openapi-ts/clients/angular) <span data-soon>Soon</span> 33 33 - [Effect](/openapi-ts/clients/effect) <span data-soon>Soon</span> 34 34 - [Legacy](/openapi-ts/clients/legacy) 35 35
+173 -61
docs/openapi-ts/clients/angular.md
··· 1 1 --- 2 - title: Angular client 3 - description: Angular client for Hey API. Compatible with all our features. 2 + title: Angular v20 Client 3 + description: Generate a type-safe Angular v20 client from OpenAPI with the Angular client for openapi-ts. Fully compatible with validators, transformers, and all core features. 4 4 --- 5 5 6 6 <script setup lang="ts"> 7 - import { embedProject } from '../../embed' 7 + import AuthorsList from '@components/AuthorsList.vue'; 8 + import Heading from '@components/Heading.vue'; 9 + import { maxScopp } from '@data/people.js'; 10 + import AngularVersionSwitcher from '@versions/AngularVersionSwitcher.vue'; 8 11 </script> 9 12 10 13 <Heading> 11 14 <h1>Angular</h1> 12 - <VersionLabel value="v1" /> 13 - <ExperimentalLabel /> 15 + <AngularVersionSwitcher /> 14 16 </Heading> 15 17 18 + ::: warning 19 + Angular client is currently in beta. The interface might change before it becomes stable. We encourage you to leave feedback on [GitHub](https://github.com/hey-api/openapi-ts/issues). 20 + ::: 21 + 16 22 ### About 17 23 18 - [Angular](https://angular.dev/) is a web framework for building fast, reliable applications. 24 + [Angular](https://angular.dev/) is a web framework that empowers developers to build fast, reliable applications. 19 25 20 - ::: warning Requirements 21 - **Angular 19+** is required for full feature support, including the experimental `httpResource` API. 22 - ::: 26 + The Angular client for Hey API generates a type-safe client from your OpenAPI spec, fully compatible with validators, transformers, and all core features. 27 + 28 + ### Collaborators 23 29 24 - ::: tip First Release 25 - Angular client support is in its first release. Share your feedback on [GitHub](https://github.com/hey-api/openapi-ts/issues). 26 - ::: 30 + <AuthorsList :people="[maxScopp]" /> 27 31 28 32 ## Features 29 33 30 - - Modern Angular patterns with signals and reactive programming 31 - - Dependency injection with `@Injectable()` decorators 32 - - Type-safe response data and errors 33 - - Experimental **httpResource** support (Angular 19+) 34 + - Angular v20 support 35 + - seamless integration with `@hey-api/openapi-ts` ecosystem 36 + - type-safe response data and errors 37 + - support for [`@Injectable()`](https://angular.dev/api/core/Injectable) decorators 38 + - response data validation and transformation 39 + - access to the original request and response 40 + - granular request and response customization options 41 + - minimal learning curve thanks to extending the underlying technology 42 + - support bundling inside the generated output 43 + 44 + ## Installation 34 45 35 - ## Usage 46 + In your [configuration](/openapi-ts/get-started), add `@hey-api/client-angular` to your plugins and you'll be ready to generate client artifacts. :tada: 36 47 37 - Add `@hey-api/client-angular` to your plugins: 48 + ::: code-group 38 49 39 - ```js 50 + ```js [config] 40 51 export default { 41 52 input: 'https://get.heyapi.dev/hey-api/backend', 42 53 output: 'src/client', 43 - plugins: [ 44 - '@hey-api/client-angular', // [!code ++] 45 - ], 54 + plugins: ['@hey-api/client-angular'], // [!code ++] 46 55 }; 47 56 ``` 48 57 49 - After generating the client, integrate it with Angular's `HttpClient` by adding `provideHeyApiClient` to your app configuration: 58 + ```sh [cli] 59 + npx @hey-api/openapi-ts \ 60 + -i https://get.heyapi.dev/hey-api/backend \ 61 + -o src/client \ 62 + -c @hey-api/client-angular # [!code ++] 63 + ``` 64 + 65 + ::: 66 + 67 + ### Providers 68 + 69 + You can use the Angular client in your application by adding `provideHeyApiClient` to your providers. 50 70 51 71 ```ts 52 - import { provideHttpClient, withFetch } from '@angular/common/http'; 53 72 import { provideHeyApiClient, client } from './client/client.gen'; 54 73 55 - export const appConfig = { 74 + export const appConfig: ApplicationConfig = { 56 75 providers: [ 57 76 provideHttpClient(withFetch()), 58 77 provideHeyApiClient(client), // [!code ++] ··· 62 81 63 82 ## Configuration 64 83 65 - ### Injectable Classes Configuration 84 + The Angular client is built as a thin wrapper on top of Angular, extending its functionality to work with Hey API. If you're already familiar with Angular, configuring your client will feel like working directly with Angular. 85 + 86 + 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. 87 + 88 + ### `setConfig()` 66 89 67 - You can configure the SDK to generate injectable classes by setting the `asClass` option to `true` in your plugin configuration. This will generate Angular services with `@Injectable()` decorators, making them available for dependency injection. 90 + 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 `HttpRequest` configuration option to `setConfig()`, and even your own [`httpClient`](#custom-httpclient) implementation. 91 + 92 + ```js 93 + import { client } from 'client/client.gen'; 94 + 95 + client.setConfig({ 96 + baseUrl: 'https://example.com', 97 + }); 98 + ``` 99 + 100 + 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. 101 + 102 + ### Runtime API 103 + 104 + 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. 68 105 69 106 ```js 70 107 export default { 71 108 input: 'https://get.heyapi.dev/hey-api/backend', 72 109 output: 'src/client', 73 110 plugins: [ 74 - '@hey-api/client-angular', 75 111 { 76 - name: '@hey-api/sdk', 77 - asClass: true, // [!code ++] 112 + name: '@hey-api/client-angular', 113 + runtimeConfigPath: './src/hey-api.ts', // [!code ++] 78 114 }, 79 115 ], 80 116 }; 81 117 ``` 82 118 83 - ::: warning 84 - While this feature is available, it is **discouraged** as it can negatively impact tree shaking, leading to larger bundle sizes. Consider using other configuration options for better optimization. 85 - ::: 119 + In our custom file, we need to export a `createClientConfig()` method. This function is a simple wrapper allowing us to override configuration values. 86 120 87 - ### Angular Providers 121 + ::: code-group 88 122 89 - Use `provideHeyApiClient` to integrate the generated client with Angular's `HttpClient`: 123 + ```ts [hey-api.ts] 124 + import type { CreateClientConfig } from './client/client.gen'; 90 125 91 - ```ts 92 - import { provideHttpClient, withFetch } from '@angular/common/http'; 93 - import { provideHeyApiClient, client } from './client/client.gen'; 94 - 95 - export const appConfig = { 96 - providers: [provideHttpClient(withFetch()), provideHeyApiClient(client)], 97 - }; 126 + export const createClientConfig: CreateClientConfig = (config) => ({ 127 + ...config, 128 + baseUrl: 'https://example.com', 129 + }); 98 130 ``` 99 131 132 + ::: 133 + 134 + 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. 135 + 100 136 ### `createClient()` 101 137 102 - Manually create a client instance for custom configurations: 138 + You can also create your own client instance. You can use it to manually send requests or point it to a different domain. 103 139 104 - ```ts 140 + ```js 105 141 import { createClient } from './client/client'; 106 142 107 143 const myClient = createClient({ ··· 109 145 }); 110 146 ``` 111 147 112 - ## Plugin Configuration 148 + You can also pass this instance to any SDK function through the `client` option. This will override the default instance from `client.gen.ts`. 113 149 114 - The `@hey-api/client-angular` plugin supports options like `throwOnError` for error handling: 150 + ```js 151 + const response = await getFoo({ 152 + client: myClient, 153 + }); 154 + ``` 155 + 156 + ### SDKs 157 + 158 + 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. 115 159 116 160 ```js 161 + const response = await getFoo({ 162 + baseUrl: 'https://example.com', // <-- override default configuration 163 + }); 164 + ``` 165 + 166 + ## `@Injectable` 167 + 168 + If you prefer to use the [`@Injectable()`](https://angular.dev/api/core/Injectable) decorators, set the `asClass` option in your SDK plugin to `true`. 169 + 170 + ::: code-group 171 + 172 + ```ts [example] 173 + @Injectable({ providedIn: 'root' }) 174 + export class FooService { 175 + // class methods 176 + } 177 + ``` 178 + 179 + ```js [config] 117 180 export default { 118 181 input: 'https://get.heyapi.dev/hey-api/backend', 119 182 output: 'src/client', 120 183 plugins: [ 184 + '@hey-api/client-angular', 121 185 { 122 - name: '@hey-api/client-angular', 123 - throwOnError: false, 186 + name: '@hey-api/sdk', 187 + asClass: true, // [!code ++] 124 188 }, 125 189 ], 126 190 }; 127 191 ``` 128 192 129 - ## httpResource 193 + ::: 194 + 195 + ## Interceptors 196 + 197 + ::: warning 198 + This section is under construction. We appreciate your patience. 199 + ::: 200 + 201 + ## Auth 202 + 203 + ::: warning 204 + This section is under construction. We appreciate your patience. 205 + ::: 206 + 207 + ## Build URL 208 + 209 + 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. 210 + 211 + ```ts 212 + type FooData = { 213 + path: { 214 + fooId: number; 215 + }; 216 + query?: { 217 + bar?: string; 218 + }; 219 + url: '/foo/{fooId}'; 220 + }; 221 + 222 + const url = client.buildUrl<FooData>({ 223 + path: { 224 + fooId: 1, 225 + }, 226 + query: { 227 + bar: 'baz', 228 + }, 229 + url: '/foo/{fooId}', 230 + }); 231 + console.log(url); // prints '/foo/1?bar=baz' 232 + ``` 130 233 131 - Angular 19 introduces a experimental api &ndash; `httpResource`, a reactive approach to data loading. Enable it with: 234 + ## Custom `httpClient` 235 + 236 + 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. 132 237 133 238 ```js 134 - export default { 135 - plugins: [ 136 - { 137 - name: '@angular/common', 138 - httpResource: { 139 - enabled: true, 140 - asClass: true, 141 - }, 142 - }, 143 - ], 144 - }; 239 + import { client } from 'client/client.gen'; 240 + 241 + client.setConfig({ 242 + httpClient: inject(CustomHttpClient), 243 + }); 145 244 ``` 245 + 246 + You can use any of the approaches mentioned in [Configuration](#configuration), depending on how granular you want your custom client to be. 247 + 248 + ## Plugins 249 + 250 + You might be also interested in the [Angular](/openapi-ts/plugins/angular) plugin. 251 + 252 + ## API 253 + 254 + 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-angular/types.d.ts) interface. 255 + 256 + <!--@include: ../../partials/examples.md--> 257 + <!--@include: ../../partials/sponsors.md-->
+257
docs/openapi-ts/clients/angular/v19.md
··· 1 + --- 2 + title: Angular v19 Client 3 + description: Generate a type-safe Angular v19 client from OpenAPI with the Angular client for openapi-ts. Fully compatible with validators, transformers, and all core features. 4 + --- 5 + 6 + <script setup lang="ts"> 7 + import AuthorsList from '@components/AuthorsList.vue'; 8 + import Heading from '@components/Heading.vue'; 9 + import { maxScopp } from '@data/people.js'; 10 + import AngularVersionSwitcher from '@versions/AngularVersionSwitcher.vue'; 11 + </script> 12 + 13 + <Heading> 14 + <h1>Angular</h1> 15 + <AngularVersionSwitcher /> 16 + </Heading> 17 + 18 + ::: warning 19 + Angular client is currently in beta. The interface might change before it becomes stable. We encourage you to leave feedback on [GitHub](https://github.com/hey-api/openapi-ts/issues). 20 + ::: 21 + 22 + ### About 23 + 24 + [Angular](https://angular.dev/) is a web framework that empowers developers to build fast, reliable applications. 25 + 26 + The Angular client for Hey API generates a type-safe client from your OpenAPI spec, fully compatible with validators, transformers, and all core features. 27 + 28 + ### Collaborators 29 + 30 + <AuthorsList :people="[maxScopp]" /> 31 + 32 + ## Features 33 + 34 + - Angular v19 support 35 + - seamless integration with `@hey-api/openapi-ts` ecosystem 36 + - type-safe response data and errors 37 + - support for [`@Injectable()`](https://angular.dev/api/core/Injectable) decorators 38 + - response data validation and transformation 39 + - access to the original request and response 40 + - granular request and response customization options 41 + - minimal learning curve thanks to extending the underlying technology 42 + - support bundling inside the generated output 43 + 44 + ## Installation 45 + 46 + In your [configuration](/openapi-ts/get-started), add `@hey-api/client-angular` to your plugins and you'll be ready to generate client artifacts. :tada: 47 + 48 + ::: code-group 49 + 50 + ```js [config] 51 + export default { 52 + input: 'https://get.heyapi.dev/hey-api/backend', 53 + output: 'src/client', 54 + plugins: ['@hey-api/client-angular'], // [!code ++] 55 + }; 56 + ``` 57 + 58 + ```sh [cli] 59 + npx @hey-api/openapi-ts \ 60 + -i https://get.heyapi.dev/hey-api/backend \ 61 + -o src/client \ 62 + -c @hey-api/client-angular # [!code ++] 63 + ``` 64 + 65 + ::: 66 + 67 + ### Providers 68 + 69 + You can use the Angular client in your application by adding `provideHeyApiClient` to your providers. 70 + 71 + ```ts 72 + import { provideHeyApiClient, client } from './client/client.gen'; 73 + 74 + export const appConfig: ApplicationConfig = { 75 + providers: [ 76 + provideHttpClient(withFetch()), 77 + provideHeyApiClient(client), // [!code ++] 78 + ], 79 + }; 80 + ``` 81 + 82 + ## Configuration 83 + 84 + The Angular client is built as a thin wrapper on top of Angular, extending its functionality to work with Hey API. If you're already familiar with Angular, configuring your client will feel like working directly with Angular. 85 + 86 + 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. 87 + 88 + ### `setConfig()` 89 + 90 + 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 `HttpRequest` configuration option to `setConfig()`, and even your own [`httpClient`](#custom-httpclient) implementation. 91 + 92 + ```js 93 + import { client } from 'client/client.gen'; 94 + 95 + client.setConfig({ 96 + baseUrl: 'https://example.com', 97 + }); 98 + ``` 99 + 100 + 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. 101 + 102 + ### Runtime API 103 + 104 + 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. 105 + 106 + ```js 107 + export default { 108 + input: 'https://get.heyapi.dev/hey-api/backend', 109 + output: 'src/client', 110 + plugins: [ 111 + { 112 + name: '@hey-api/client-angular', 113 + runtimeConfigPath: './src/hey-api.ts', // [!code ++] 114 + }, 115 + ], 116 + }; 117 + ``` 118 + 119 + In our custom file, we need to export a `createClientConfig()` method. This function is a simple wrapper allowing us to override configuration values. 120 + 121 + ::: code-group 122 + 123 + ```ts [hey-api.ts] 124 + import type { CreateClientConfig } from './client/client.gen'; 125 + 126 + export const createClientConfig: CreateClientConfig = (config) => ({ 127 + ...config, 128 + baseUrl: 'https://example.com', 129 + }); 130 + ``` 131 + 132 + ::: 133 + 134 + 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. 135 + 136 + ### `createClient()` 137 + 138 + You can also create your own client instance. You can use it to manually send requests or point it to a different domain. 139 + 140 + ```js 141 + import { createClient } from './client/client'; 142 + 143 + const myClient = createClient({ 144 + baseUrl: 'https://example.com', 145 + }); 146 + ``` 147 + 148 + You can also pass this instance to any SDK function through the `client` option. This will override the default instance from `client.gen.ts`. 149 + 150 + ```js 151 + const response = await getFoo({ 152 + client: myClient, 153 + }); 154 + ``` 155 + 156 + ### SDKs 157 + 158 + 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. 159 + 160 + ```js 161 + const response = await getFoo({ 162 + baseUrl: 'https://example.com', // <-- override default configuration 163 + }); 164 + ``` 165 + 166 + ## `@Injectable` 167 + 168 + If you prefer to use the [`@Injectable()`](https://angular.dev/api/core/Injectable) decorators, set the `asClass` option in your SDK plugin to `true`. 169 + 170 + ::: code-group 171 + 172 + ```ts [example] 173 + @Injectable({ providedIn: 'root' }) 174 + export class FooService { 175 + // class methods 176 + } 177 + ``` 178 + 179 + ```js [config] 180 + export default { 181 + input: 'https://get.heyapi.dev/hey-api/backend', 182 + output: 'src/client', 183 + plugins: [ 184 + '@hey-api/client-angular', 185 + { 186 + name: '@hey-api/sdk', 187 + asClass: true, // [!code ++] 188 + }, 189 + ], 190 + }; 191 + ``` 192 + 193 + ::: 194 + 195 + ## Interceptors 196 + 197 + ::: warning 198 + This section is under construction. We appreciate your patience. 199 + ::: 200 + 201 + ## Auth 202 + 203 + ::: warning 204 + This section is under construction. We appreciate your patience. 205 + ::: 206 + 207 + ## Build URL 208 + 209 + 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. 210 + 211 + ```ts 212 + type FooData = { 213 + path: { 214 + fooId: number; 215 + }; 216 + query?: { 217 + bar?: string; 218 + }; 219 + url: '/foo/{fooId}'; 220 + }; 221 + 222 + const url = client.buildUrl<FooData>({ 223 + path: { 224 + fooId: 1, 225 + }, 226 + query: { 227 + bar: 'baz', 228 + }, 229 + url: '/foo/{fooId}', 230 + }); 231 + console.log(url); // prints '/foo/1?bar=baz' 232 + ``` 233 + 234 + ## Custom `httpClient` 235 + 236 + 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. 237 + 238 + ```js 239 + import { client } from 'client/client.gen'; 240 + 241 + client.setConfig({ 242 + httpClient: inject(CustomHttpClient), 243 + }); 244 + ``` 245 + 246 + You can use any of the approaches mentioned in [Configuration](#configuration), depending on how granular you want your custom client to be. 247 + 248 + ## Plugins 249 + 250 + You might be also interested in the [Angular](/openapi-ts/plugins/angular/v19) plugin. 251 + 252 + ## API 253 + 254 + 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-angular/types.d.ts) interface. 255 + 256 + <!--@include: ../../../partials/examples.md--> 257 + <!--@include: ../../../partials/sponsors.md-->
+8 -2
docs/openapi-ts/clients/axios.md
··· 1 1 --- 2 - title: Axios client 3 - description: Axios client for Hey API. Compatible with all our features. 2 + title: Axios v1 Client 3 + description: Generate a type-safe Axios v1 client from OpenAPI with the Axios client for openapi-ts. Fully compatible with validators, transformers, and all core features. 4 4 --- 5 5 6 6 <script setup lang="ts"> 7 + import Heading from '@components/Heading.vue'; 8 + import VersionLabel from '@components/VersionLabel.vue'; 9 + 7 10 import { embedProject } from '../../embed' 8 11 </script> 9 12 ··· 16 19 17 20 [Axios](https://axios-http.com) is a simple promise based HTTP client for the browser and Node.js. Axios provides a simple to use library in a small package with a very extensible interface. 18 21 22 + The Axios client for Hey API generates a type-safe client from your OpenAPI spec, fully compatible with validators, transformers, and all core features. 23 + 19 24 ### Demo 20 25 21 26 <button class="buttonLink" @click="(event) => embedProject('hey-api-client-axios-example')(event)"> ··· 24 29 25 30 ## Features 26 31 32 + - Axios v1 support 27 33 - seamless integration with `@hey-api/openapi-ts` ecosystem 28 34 - type-safe response data and errors 29 35 - response data validation and transformation
+4
docs/openapi-ts/clients/effect.md
··· 3 3 description: Effect client for Hey API. Compatible with all our features. 4 4 --- 5 5 6 + <script setup lang="ts"> 7 + import FeatureStatus from '@components/FeatureStatus.vue'; 8 + </script> 9 + 6 10 # Effect <span data-soon>soon</span> 7 11 8 12 <FeatureStatus issueNumber=2082 name="Effect" />
+4 -2
docs/openapi-ts/clients/fetch.md
··· 1 1 --- 2 - title: Fetch API client 3 - description: Fetch API client for Hey API. Compatible with all our features. 2 + title: Fetch API Client 3 + description: Generate a type-safe Fetch API client from OpenAPI with the Fetch API client for openapi-ts. Fully compatible with validators, transformers, and all core features. 4 4 --- 5 5 6 6 <script setup lang="ts"> ··· 12 12 ### About 13 13 14 14 The [Fetch API](https://developer.mozilla.org/docs/Web/API/Fetch_API) provides an interface for fetching resources (including across the network). It is a more powerful and flexible replacement for XMLHttpRequest. 15 + 16 + The Fetch API client for Hey API generates a type-safe client from your OpenAPI spec, fully compatible with validators, transformers, and all core features. 15 17 16 18 ### Demo 17 19
+3 -5
docs/openapi-ts/clients/next-js.md
··· 1 1 --- 2 - title: Next.js client 3 - description: Next.js client for Hey API. Compatible with all our features. 2 + title: Next.js Client 3 + description: Generate a type-safe Next.js client from OpenAPI with the Next.js client for openapi-ts. Fully compatible with validators, transformers, and all core features. 4 4 --- 5 5 6 6 # Next.js ··· 9 9 10 10 [Next.js](https://nextjs.org) is the React framework for the web. Used by some of the world's largest companies, Next.js enables you to create high-quality web applications with the power of React components. 11 11 12 - <!-- <button class="buttonLink" @click="(event) => embedProject('hey-api-client-next-example')(event)"> 13 - Launch demo 14 - </button> --> 12 + The Next.js client for Hey API generates a type-safe client from your OpenAPI spec, fully compatible with validators, transformers, and all core features. 15 13 16 14 ## Features 17 15
+9 -5
docs/openapi-ts/clients/nuxt.md
··· 1 1 --- 2 - title: Nuxt client 3 - description: Nuxt client for Hey API. Compatible with all our features. 2 + title: Nuxt v3 Client 3 + description: Generate a type-safe Nuxt v3 client from OpenAPI with the Nuxt client for openapi-ts. Fully compatible with validators, transformers, and all core features. 4 4 --- 5 + 6 + <script setup lang="ts"> 7 + import Heading from '@components/Heading.vue'; 8 + import VersionLabel from '@components/VersionLabel.vue'; 9 + </script> 5 10 6 11 <Heading> 7 12 <h1>Nuxt</h1> ··· 16 21 17 22 [Nuxt](https://nuxt.com) is an open source framework that makes web development intuitive and powerful. 18 23 19 - <!-- <button class="buttonLink" @click="(event) => embedProject('hey-api-client-fetch-example')(event)"> 20 - Launch demo 21 - </button> --> 24 + The Nuxt client for Hey API generates a type-safe client from your OpenAPI spec, fully compatible with validators, transformers, and all core features. 22 25 23 26 ## Features 24 27 28 + - Nuxt v3 support 25 29 - seamless integration with `@hey-api/openapi-ts` ecosystem 26 30 - type-safe response data and errors 27 31 - response data validation and transformation
+1
docs/openapi-ts/plugins.md
··· 25 25 - [`@tanstack/solid-query`](/openapi-ts/plugins/tanstack-query) 26 26 - [`@tanstack/svelte-query`](/openapi-ts/plugins/tanstack-query) 27 27 - [`@tanstack/vue-query`](/openapi-ts/plugins/tanstack-query) 28 + - [`@angular/common`](/openapi-ts/plugins/angular) 28 29 - [`fastify`](/openapi-ts/plugins/fastify) 29 30 - [`valibot`](/openapi-ts/plugins/valibot) 30 31 - [`zod`](/openapi-ts/plugins/zod)
+4
docs/openapi-ts/plugins/adonis.md
··· 3 3 description: AdonisJS plugin for Hey API. Compatible with all our features. 4 4 --- 5 5 6 + <script setup lang="ts"> 7 + import FeatureStatus from '@components/FeatureStatus.vue'; 8 + </script> 9 + 6 10 # AdonisJS <span data-soon>soon</span> 7 11 8 12 <FeatureStatus issueNumber=2364 name="AdonisJS" />
+4
docs/openapi-ts/plugins/ajv.md
··· 3 3 description: Ajv plugin for Hey API. Compatible with all our features. 4 4 --- 5 5 6 + <script setup lang="ts"> 7 + import FeatureStatus from '@components/FeatureStatus.vue'; 8 + </script> 9 + 6 10 # Ajv <span data-soon>soon</span> 7 11 8 12 <FeatureStatus issueNumber=1476 name="Ajv" />
+123
docs/openapi-ts/plugins/angular.md
··· 1 + --- 2 + title: Angular v20 Plugin 3 + description: Generate Angular v20 HTTP requests and resources from OpenAPI with the Angular plugin for openapi-ts. Fully compatible with validators, transformers, and all core features. 4 + --- 5 + 6 + <script setup lang="ts"> 7 + import AuthorsList from '@components/AuthorsList.vue'; 8 + import Heading from '@components/Heading.vue'; 9 + import { maxScopp } from '@data/people.js'; 10 + import AngularVersionSwitcher from '@versions/AngularVersionSwitcher.vue'; 11 + </script> 12 + 13 + <Heading> 14 + <h1>Angular</h1> 15 + <AngularVersionSwitcher /> 16 + </Heading> 17 + 18 + ::: warning 19 + Angular client is currently in beta. The interface might change before it becomes stable. We encourage you to leave feedback on [GitHub](https://github.com/hey-api/openapi-ts/issues). 20 + ::: 21 + 22 + ### About 23 + 24 + [Angular](https://angular.dev/) is a web framework that empowers developers to build fast, reliable applications. 25 + 26 + The Angular plugin for Hey API generates HTTP requests and resources from your OpenAPI spec, fully compatible with validators, transformers, and all core features. 27 + 28 + ### Collaborators 29 + 30 + <AuthorsList :people="[maxScopp]" /> 31 + 32 + ## Features 33 + 34 + - Angular v20 support 35 + - seamless integration with `@hey-api/openapi-ts` ecosystem 36 + - generate HTTP requests 37 + - generate HTTP resources 38 + - minimal learning curve thanks to extending the underlying technology 39 + 40 + ## Installation 41 + 42 + In your [configuration](/openapi-ts/get-started), add `@angular/common` to your plugins and you'll be ready to generate Angular artifacts. :tada: 43 + 44 + ```js 45 + export default { 46 + input: 'https://get.heyapi.dev/hey-api/backend', 47 + output: 'src/client', 48 + plugins: [ 49 + // ...other plugins 50 + '@angular/common', // [!code ++] 51 + ], 52 + }; 53 + ``` 54 + 55 + ## Output 56 + 57 + The Angular plugin will generate the following artifacts, depending on the input specification. 58 + 59 + ## Requests 60 + 61 + A single function is generated for each endpoint. It returns an [`HttpRequest`](https://angular.dev/api/common/http/HttpRequest) result. 62 + 63 + ::: code-group 64 + 65 + ```ts [example] 66 + export const addPetRequest = (options) => 67 + client.requestOptions({ 68 + method: 'POST', 69 + responseStyle: 'data', 70 + url: '/pet', 71 + ...options, 72 + }); 73 + ``` 74 + 75 + ```js [config] 76 + export default { 77 + input: 'https://get.heyapi.dev/hey-api/backend', 78 + output: 'src/client', 79 + plugins: [ 80 + // ...other plugins 81 + { 82 + name: '@angular/common', 83 + httpRequests: true, // [!code ++] 84 + }, 85 + ], 86 + }; 87 + ``` 88 + 89 + ::: 90 + 91 + ## Resources 92 + 93 + A single function is generated for each endpoint. It returns a result from [`httpResource`](https://angular.dev/api/common/http/httpResource) call. 94 + 95 + ::: code-group 96 + 97 + ```ts [example] 98 + export const addPetResource = (options) => 99 + httpResource(() => addPetRequest(options())); 100 + ``` 101 + 102 + ```js [config] 103 + export default { 104 + input: 'https://get.heyapi.dev/hey-api/backend', 105 + output: 'src/client', 106 + plugins: [ 107 + // ...other plugins 108 + { 109 + name: '@angular/common', 110 + httpResources: true, // [!code ++] 111 + }, 112 + ], 113 + }; 114 + ``` 115 + 116 + ::: 117 + 118 + ## API 119 + 120 + 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/@angular/common/types.d.ts) interface. 121 + 122 + <!--@include: ../../partials/examples.md--> 123 + <!--@include: ../../partials/sponsors.md-->
+123
docs/openapi-ts/plugins/angular/v19.md
··· 1 + --- 2 + title: Angular v19 Plugin 3 + description: Generate Angular v19 HTTP requests and resources from OpenAPI with the Angular plugin for openapi-ts. Fully compatible with validators, transformers, and all core features. 4 + --- 5 + 6 + <script setup lang="ts"> 7 + import AuthorsList from '@components/AuthorsList.vue'; 8 + import Heading from '@components/Heading.vue'; 9 + import { maxScopp } from '@data/people.js'; 10 + import AngularVersionSwitcher from '@versions/AngularVersionSwitcher.vue'; 11 + </script> 12 + 13 + <Heading> 14 + <h1>Angular</h1> 15 + <AngularVersionSwitcher /> 16 + </Heading> 17 + 18 + ::: warning 19 + Angular client is currently in beta. The interface might change before it becomes stable. We encourage you to leave feedback on [GitHub](https://github.com/hey-api/openapi-ts/issues). 20 + ::: 21 + 22 + ### About 23 + 24 + [Angular](https://angular.dev/) is a web framework that empowers developers to build fast, reliable applications. 25 + 26 + The Angular plugin for Hey API generates HTTP requests and resources from your OpenAPI spec, fully compatible with validators, transformers, and all core features. 27 + 28 + ### Collaborators 29 + 30 + <AuthorsList :people="[maxScopp]" /> 31 + 32 + ## Features 33 + 34 + - Angular v19 support 35 + - seamless integration with `@hey-api/openapi-ts` ecosystem 36 + - generate HTTP requests 37 + - generate HTTP resources 38 + - minimal learning curve thanks to extending the underlying technology 39 + 40 + ## Installation 41 + 42 + In your [configuration](/openapi-ts/get-started), add `@angular/common` to your plugins and you'll be ready to generate Angular artifacts. :tada: 43 + 44 + ```js 45 + export default { 46 + input: 'https://get.heyapi.dev/hey-api/backend', 47 + output: 'src/client', 48 + plugins: [ 49 + // ...other plugins 50 + '@angular/common', // [!code ++] 51 + ], 52 + }; 53 + ``` 54 + 55 + ## Output 56 + 57 + The Angular plugin will generate the following artifacts, depending on the input specification. 58 + 59 + ## Requests 60 + 61 + A single function is generated for each endpoint. It returns an [`HttpRequest`](https://v19.angular.dev/api/common/http/HttpRequest) result. 62 + 63 + ::: code-group 64 + 65 + ```ts [example] 66 + export const addPetRequest = (options) => 67 + client.requestOptions({ 68 + method: 'POST', 69 + responseStyle: 'data', 70 + url: '/pet', 71 + ...options, 72 + }); 73 + ``` 74 + 75 + ```js [config] 76 + export default { 77 + input: 'https://get.heyapi.dev/hey-api/backend', 78 + output: 'src/client', 79 + plugins: [ 80 + // ...other plugins 81 + { 82 + name: '@angular/common', 83 + httpRequests: true, // [!code ++] 84 + }, 85 + ], 86 + }; 87 + ``` 88 + 89 + ::: 90 + 91 + ## Resources 92 + 93 + A single function is generated for each endpoint. It returns a result from [`httpResource`](https://v19.angular.dev/api/common/http/httpResource) call. 94 + 95 + ::: code-group 96 + 97 + ```ts [example] 98 + export const addPetResource = (options) => 99 + httpResource(() => addPetRequest(options())); 100 + ``` 101 + 102 + ```js [config] 103 + export default { 104 + input: 'https://get.heyapi.dev/hey-api/backend', 105 + output: 'src/client', 106 + plugins: [ 107 + // ...other plugins 108 + { 109 + name: '@angular/common', 110 + httpResources: true, // [!code ++] 111 + }, 112 + ], 113 + }; 114 + ``` 115 + 116 + ::: 117 + 118 + ## API 119 + 120 + 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/@angular/common/types.d.ts) interface. 121 + 122 + <!--@include: ../../partials/examples.md--> 123 + <!--@include: ../../partials/sponsors.md-->
+4
docs/openapi-ts/plugins/arktype.md
··· 3 3 description: Arktype plugin for Hey API. Compatible with all our features. 4 4 --- 5 5 6 + <script setup lang="ts"> 7 + import FeatureStatus from '@components/FeatureStatus.vue'; 8 + </script> 9 + 6 10 # Arktype <span data-soon>soon</span> 7 11 8 12 <FeatureStatus issueNumber=1473 name="Arktype" />
+4
docs/openapi-ts/plugins/express.md
··· 3 3 description: Express plugin for Hey API. Compatible with all our features. 4 4 --- 5 5 6 + <script setup lang="ts"> 7 + import FeatureStatus from '@components/FeatureStatus.vue'; 8 + </script> 9 + 6 10 # Express <span data-soon>soon</span> 7 11 8 12 <FeatureStatus issueNumber=1484 name="Express" />
+4
docs/openapi-ts/plugins/faker.md
··· 3 3 description: Faker plugin for Hey API. Compatible with all our features. 4 4 --- 5 5 6 + <script setup lang="ts"> 7 + import FeatureStatus from '@components/FeatureStatus.vue'; 8 + </script> 9 + 6 10 # Faker <span data-soon>soon</span> 7 11 8 12 <FeatureStatus issueNumber=1485 name="Faker" />
+8 -9
docs/openapi-ts/plugins/fastify.md
··· 3 3 description: Generate Fastify v5 route handlers from OpenAPI with the Fastify plugin for openapi-ts. Fully compatible with validators, transformers, and all core features. 4 4 --- 5 5 6 + <script setup lang="ts"> 7 + import AuthorsList from '@components/AuthorsList.vue'; 8 + import Heading from '@components/Heading.vue'; 9 + import { jacobCohen } from '@data/people.js'; 10 + import VersionLabel from '@components/VersionLabel.vue'; 11 + </script> 12 + 6 13 <Heading> 7 14 <h1>Fastify</h1> 8 15 <VersionLabel value="v5" /> ··· 18 25 19 26 The Fastify plugin for Hey API generates route handlers from your OpenAPI spec, fully compatible with all core features. 20 27 21 - <!-- ### Demo 22 - 23 - <button class="buttonLink" @click="(event) => embedProject('hey-api-client-fetch-plugin-fastify-example')(event)"> 24 - StackBlitz 25 - </button> --> 26 - 27 28 ### Collaborators 28 29 29 - <AuthorsList :people="[ 30 - { name: 'Jacob Cohen', github: 'https://github.com/jacobinu' }, 31 - ]" /> 30 + <AuthorsList :people="[jacobCohen]" /> 32 31 33 32 ## Features 34 33
+4
docs/openapi-ts/plugins/hono.md
··· 3 3 description: Hono plugin for Hey API. Compatible with all our features. 4 4 --- 5 5 6 + <script setup lang="ts"> 7 + import FeatureStatus from '@components/FeatureStatus.vue'; 8 + </script> 9 + 6 10 # Hono <span data-soon>soon</span> 7 11 8 12 <FeatureStatus issueNumber=1483 name="Hono" />
+4
docs/openapi-ts/plugins/joi.md
··· 3 3 description: Joi plugin for Hey API. Compatible with all our features. 4 4 --- 5 5 6 + <script setup lang="ts"> 7 + import FeatureStatus from '@components/FeatureStatus.vue'; 8 + </script> 9 + 6 10 # Joi <span data-soon>soon</span> 7 11 8 12 <FeatureStatus issueNumber=1477 name="Joi" />
+4
docs/openapi-ts/plugins/koa.md
··· 3 3 description: Koa plugin for Hey API. Compatible with all our features. 4 4 --- 5 5 6 + <script setup lang="ts"> 7 + import FeatureStatus from '@components/FeatureStatus.vue'; 8 + </script> 9 + 6 10 # Koa <span data-soon>soon</span> 7 11 8 12 <FeatureStatus issueNumber=1482 name="Koa" />
+4
docs/openapi-ts/plugins/msw.md
··· 3 3 description: MSW plugin for Hey API. Compatible with all our features. 4 4 --- 5 5 6 + <script setup lang="ts"> 7 + import FeatureStatus from '@components/FeatureStatus.vue'; 8 + </script> 9 + 6 10 # MSW <span data-soon>soon</span> 7 11 8 12 <FeatureStatus issueNumber=1486 name="MSW" />
+4
docs/openapi-ts/plugins/nest.md
··· 3 3 description: Nest plugin for Hey API. Compatible with all our features. 4 4 --- 5 5 6 + <script setup lang="ts"> 7 + import FeatureStatus from '@components/FeatureStatus.vue'; 8 + </script> 9 + 6 10 # Nest <span data-soon>soon</span> 7 11 8 12 <FeatureStatus issueNumber=1481 name="Nest" />
+4
docs/openapi-ts/plugins/nock.md
··· 3 3 description: Nock plugin for Hey API. Compatible with all our features. 4 4 --- 5 5 6 + <script setup lang="ts"> 7 + import FeatureStatus from '@components/FeatureStatus.vue'; 8 + </script> 9 + 6 10 # Nock <span data-soon>soon</span> 7 11 8 12 <FeatureStatus issueNumber=1487 name="Nock" />
+4
docs/openapi-ts/plugins/pinia-colada.md
··· 3 3 description: Pinia Colada plugin for Hey API. Compatible with all our features. 4 4 --- 5 5 6 + <script setup lang="ts"> 7 + import FeatureStatus from '@components/FeatureStatus.vue'; 8 + </script> 9 + 6 10 # Pinia Colada <span data-soon>soon</span> 7 11 8 12 <FeatureStatus issueNumber=1242 name="Pinia Colada" />
+4
docs/openapi-ts/plugins/superstruct.md
··· 3 3 description: Superstruct plugin for Hey API. Compatible with all our features. 4 4 --- 5 5 6 + <script setup lang="ts"> 7 + import FeatureStatus from '@components/FeatureStatus.vue'; 8 + </script> 9 + 6 10 # Superstruct <span data-soon>soon</span> 7 11 8 12 <FeatureStatus issueNumber=1489 name="Superstruct" />
+4
docs/openapi-ts/plugins/supertest.md
··· 3 3 description: Supertest plugin for Hey API. Compatible with all our features. 4 4 --- 5 5 6 + <script setup lang="ts"> 7 + import FeatureStatus from '@components/FeatureStatus.vue'; 8 + </script> 9 + 6 10 # Supertest <span data-soon>soon</span> 7 11 8 12 <FeatureStatus issueNumber=1488 name="Supertest" />
+4
docs/openapi-ts/plugins/swr.md
··· 3 3 description: SWR plugin for Hey API. Compatible with all our features. 4 4 --- 5 5 6 + <script setup lang="ts"> 7 + import FeatureStatus from '@components/FeatureStatus.vue'; 8 + </script> 9 + 6 10 # SWR <span data-soon>soon</span> 7 11 8 12 <FeatureStatus issueNumber=1479 name="SWR" />
+3
docs/openapi-ts/plugins/tanstack-query.md
··· 4 4 --- 5 5 6 6 <script setup lang="ts"> 7 + import Heading from '@components/Heading.vue'; 8 + import VersionLabel from '@components/VersionLabel.vue'; 9 + 7 10 import { embedProject } from '../../embed' 8 11 </script> 9 12
+4
docs/openapi-ts/plugins/typebox.md
··· 3 3 description: TypeBox plugin for Hey API. Compatible with all our features. 4 4 --- 5 5 6 + <script setup lang="ts"> 7 + import FeatureStatus from '@components/FeatureStatus.vue'; 8 + </script> 9 + 6 10 # TypeBox <span data-soon>soon</span> 7 11 8 12 <FeatureStatus issueNumber=1475 name="TypeBox" />
+4 -9
docs/openapi-ts/plugins/valibot.md
··· 3 3 description: Generate Valibot v1 schemas from OpenAPI with the Valibot plugin for openapi-ts. Fully compatible with validators, transformers, and all core features. 4 4 --- 5 5 6 - <!-- <script setup lang="ts"> 7 - import { embedProject } from '../../embed' 8 - </script> --> 6 + <script setup lang="ts"> 7 + import Heading from '@components/Heading.vue'; 8 + import VersionLabel from '@components/VersionLabel.vue'; 9 + </script> 9 10 10 11 <Heading> 11 12 <h1>Valibot</h1> ··· 17 18 [Valibot](https://valibot.dev) is the open source schema library for TypeScript with bundle size, type safety and developer experience in mind. 18 19 19 20 The Valibot plugin for Hey API generates schemas from your OpenAPI spec, fully compatible with validators, transformers, and all core features. 20 - 21 - <!-- ### Demo 22 - 23 - <button class="buttonLink" @click="(event) => embedProject('hey-api-client-fetch-plugin-valibot-example')(event)"> 24 - Launch demo 25 - </button> --> 26 21 27 22 ## Features 28 23
+4
docs/openapi-ts/plugins/yup.md
··· 3 3 description: Yup plugin for Hey API. Compatible with all our features. 4 4 --- 5 5 6 + <script setup lang="ts"> 7 + import FeatureStatus from '@components/FeatureStatus.vue'; 8 + </script> 9 + 6 10 # Yup <span data-soon>soon</span> 7 11 8 12 <FeatureStatus issueNumber=1478 name="Yup" />
+5 -10
docs/openapi-ts/plugins/zod.md
··· 4 4 --- 5 5 6 6 <script setup lang="ts"> 7 - // import { embedProject } from '../../embed' 8 - import ZodHeading from './zod/ZodHeading.vue'; 7 + import Heading from '@components/Heading.vue'; 8 + import ZodVersionSwitcher from '@versions/ZodVersionSwitcher.vue'; 9 9 </script> 10 10 11 - <ZodHeading> 11 + <Heading> 12 12 <h1>Zod</h1> 13 - </ZodHeading> 13 + <ZodVersionSwitcher /> 14 + </Heading> 14 15 15 16 ### About 16 17 17 18 [Zod](https://zod.dev) is a TypeScript-first schema validation library with static type inference. 18 19 19 20 The Zod plugin for Hey API generates schemas from your OpenAPI spec, fully compatible with validators, transformers, and all core features. 20 - 21 - <!-- ### Demo 22 - 23 - <button class="buttonLink" @click="(event) => embedProject('hey-api-client-fetch-plugin-zod-example')(event)"> 24 - Launch demo 25 - </button> --> 26 21 27 22 ## Features 28 23
+3 -4
docs/openapi-ts/plugins/zod/ZodHeading.vue docs/.vitepress/theme/versions/ZodVersionSwitcher.vue
··· 1 1 <script setup lang="ts"> 2 + import VersionSwitcher from '@components/VersionSwitcher.vue'; 3 + 2 4 const versions = [ 3 5 { 4 6 label: 'Zod 4', ··· 19 21 </script> 20 22 21 23 <template> 22 - <Heading> 23 - <slot /> 24 - <VersionSwitcher :values="versions" default="v4" /> 25 - </Heading> 24 + <VersionSwitcher :values="versions" default="v4" /> 26 25 </template>
+5 -10
docs/openapi-ts/plugins/zod/mini.md
··· 4 4 --- 5 5 6 6 <script setup lang="ts"> 7 - // import { embedProject } from '../../embed' 8 - import ZodHeading from './ZodHeading.vue'; 7 + import Heading from '@components/Heading.vue'; 8 + import ZodVersionSwitcher from '@versions/ZodVersionSwitcher.vue'; 9 9 </script> 10 10 11 - <ZodHeading> 11 + <Heading> 12 12 <h1>Zod</h1> 13 - </ZodHeading> 13 + <ZodVersionSwitcher /> 14 + </Heading> 14 15 15 16 ### About 16 17 17 18 [Zod](https://zod.dev) is a TypeScript-first schema validation library with static type inference. 18 19 19 20 The Zod plugin for Hey API generates schemas from your OpenAPI spec, fully compatible with validators, transformers, and all core features. 20 - 21 - <!-- ### Demo 22 - 23 - <button class="buttonLink" @click="(event) => embedProject('hey-api-client-fetch-plugin-zod-example')(event)"> 24 - Launch demo 25 - </button> --> 26 21 27 22 ## Features 28 23
+5 -10
docs/openapi-ts/plugins/zod/v3.md
··· 4 4 --- 5 5 6 6 <script setup lang="ts"> 7 - // import { embedProject } from '../../embed' 8 - import ZodHeading from './ZodHeading.vue'; 7 + import Heading from '@components/Heading.vue'; 8 + import ZodVersionSwitcher from '@versions/ZodVersionSwitcher.vue'; 9 9 </script> 10 10 11 - <ZodHeading> 11 + <Heading> 12 12 <h1>Zod</h1> 13 - </ZodHeading> 13 + <ZodVersionSwitcher /> 14 + </Heading> 14 15 15 16 ### About 16 17 17 18 [Zod](https://v3.zod.dev/) is a TypeScript-first schema validation library with static type inference. 18 19 19 20 The Zod plugin for Hey API generates schemas from your OpenAPI spec, fully compatible with validators, transformers, and all core features. 20 - 21 - <!-- ### Demo 22 - 23 - <button class="buttonLink" @click="(event) => embedProject('hey-api-client-fetch-plugin-zod-example')(event)"> 24 - Launch demo 25 - </button> --> 26 21 27 22 ## Features 28 23
+4
docs/openapi-ts/plugins/zustand.md
··· 3 3 description: Zustand plugin for Hey API. Compatible with all our features. 4 4 --- 5 5 6 + <script setup lang="ts"> 7 + import FeatureStatus from '@components/FeatureStatus.vue'; 8 + </script> 9 + 6 10 # Zustand <span data-soon>soon</span> 7 11 8 12 <FeatureStatus issueNumber=1480 name="Zustand" />
+1
docs/openapi-ts/web-frameworks.md
··· 11 11 12 12 Hey API natively supports the following frameworks. 13 13 14 + - [Angular](/openapi-ts/plugins/angular) 14 15 - [Fastify](/openapi-ts/plugins/fastify) 15 16 - [Adonis](/openapi-ts/plugins/adonis) <span data-soon>Soon</span> 16 17 - [Express](/openapi-ts/plugins/express) <span data-soon>Soon</span>
+11
docs/tsconfig.json
··· 1 + { 2 + "compilerOptions": { 3 + "baseUrl": ".", 4 + "paths": { 5 + "@components/*": ["./.vitepress/theme/components/*"], 6 + "@data": ["./data/*"], 7 + "@versions/*": ["./.vitepress/theme/versions/*"] 8 + } 9 + }, 10 + "include": [".vitepress/**/*", "./**/*.ts", "./**/*.vue"] 11 + }
+5
examples/openapi-ts-angular-common/src/client/index.ts
··· 1 + // This file is auto-generated by @hey-api/openapi-ts 2 + export * from './@angular/common/http/requests.gen'; 3 + export * from './@angular/common/http/resources.gen'; 4 + export * from './sdk.gen'; 5 + export * from './types.gen';
examples/openapi-ts-angular-resource/.editorconfig examples/openapi-ts-angular-common/.editorconfig
examples/openapi-ts-angular-resource/.gitignore examples/openapi-ts-angular-common/.gitignore
examples/openapi-ts-angular-resource/.vscode/extensions.json examples/openapi-ts-angular-common/.vscode/extensions.json
examples/openapi-ts-angular-resource/.vscode/launch.json examples/openapi-ts-angular-common/.vscode/launch.json
examples/openapi-ts-angular-resource/.vscode/tasks.json examples/openapi-ts-angular-common/.vscode/tasks.json
examples/openapi-ts-angular-resource/README.md examples/openapi-ts-angular-common/README.md
examples/openapi-ts-angular-resource/angular.json examples/openapi-ts-angular-common/angular.json
+3 -2
examples/openapi-ts-angular-resource/openapi-ts.config.ts examples/openapi-ts-angular-common/openapi-ts.config.ts
··· 14 14 throwOnError: true, 15 15 }, 16 16 { 17 - httpResource: { 17 + exportFromIndex: true, 18 + httpRequests: true, 19 + httpResources: { 18 20 asClass: true, 19 - enabled: true, 20 21 }, 21 22 name: '@angular/common', 22 23 },
examples/openapi-ts-angular-resource/package-lock.json examples/openapi-ts-angular-common/package-lock.json
+1 -1
examples/openapi-ts-angular-resource/package.json examples/openapi-ts-angular-common/package.json
··· 1 1 { 2 - "name": "@example/openapi-ts-angular-resource", 2 + "name": "@example/openapi-ts-angular-common", 3 3 "private": true, 4 4 "version": "0.0.0", 5 5 "scripts": {
examples/openapi-ts-angular-resource/public/favicon.ico examples/openapi-ts-angular-common/public/favicon.ico
examples/openapi-ts-angular-resource/src/app/app.component.css examples/openapi-ts-angular-common/src/app/app.component.css
examples/openapi-ts-angular-resource/src/app/app.component.html examples/openapi-ts-angular-common/src/app/app.component.html
examples/openapi-ts-angular-resource/src/app/app.component.spec.ts examples/openapi-ts-angular-common/src/app/app.component.spec.ts
examples/openapi-ts-angular-resource/src/app/app.component.ts examples/openapi-ts-angular-common/src/app/app.component.ts
examples/openapi-ts-angular-resource/src/app/app.config.server.ts examples/openapi-ts-angular-common/src/app/app.config.server.ts
examples/openapi-ts-angular-resource/src/app/app.config.ts examples/openapi-ts-angular-common/src/app/app.config.ts
examples/openapi-ts-angular-resource/src/app/app.routes.server.ts examples/openapi-ts-angular-common/src/app/app.routes.server.ts
examples/openapi-ts-angular-resource/src/app/app.routes.ts examples/openapi-ts-angular-common/src/app/app.routes.ts
examples/openapi-ts-angular-resource/src/app/demo/demo.css examples/openapi-ts-angular-common/src/app/demo/demo.css
examples/openapi-ts-angular-resource/src/app/demo/demo.html examples/openapi-ts-angular-common/src/app/demo/demo.html
+2 -2
examples/openapi-ts-angular-resource/src/app/demo/demo.ts examples/openapi-ts-angular-common/src/app/demo/demo.ts
··· 2 2 import { Component, inject, signal } from '@angular/core'; 3 3 import { RouterOutlet } from '@angular/router'; 4 4 5 - import { PetResources } from '../../client'; 5 + import { PetServiceResources } from '../../client'; 6 6 7 7 @Component({ 8 8 host: { ngSkipHydration: 'true' }, ··· 12 12 templateUrl: './demo.html', 13 13 }) 14 14 export class Demo { 15 - #petResources = inject(PetResources); 15 + #petResources = inject(PetServiceResources); 16 16 17 17 petId = signal(0); 18 18
+19 -19
examples/openapi-ts-angular-resource/src/client/@angular/common/http/httpRequests.gen.ts examples/openapi-ts-angular-common/src/client/@angular/common/http/requests.gen.ts
··· 33 33 export const addPetRequest = <ThrowOnError extends boolean = false>( 34 34 options: Options<AddPetData, ThrowOnError>, 35 35 ): HttpRequest<unknown> => 36 - (options?.client ? options.client : _heyApiClient).requestOptions({ 36 + (options?.client ?? _heyApiClient).requestOptions({ 37 37 method: 'POST', 38 38 responseStyle: 'data', 39 39 url: '/pet', ··· 47 47 export const updatePetRequest = <ThrowOnError extends boolean = false>( 48 48 options: Options<UpdatePetData, ThrowOnError>, 49 49 ): HttpRequest<unknown> => 50 - (options?.client ? options.client : _heyApiClient).requestOptions({ 50 + (options?.client ?? _heyApiClient).requestOptions({ 51 51 method: 'PUT', 52 52 responseStyle: 'data', 53 53 url: '/pet', ··· 61 61 export const findPetsByStatusRequest = <ThrowOnError extends boolean = false>( 62 62 options: Options<FindPetsByStatusData, ThrowOnError>, 63 63 ): HttpRequest<unknown> => 64 - (options?.client ? options.client : _heyApiClient).requestOptions({ 64 + (options?.client ?? _heyApiClient).requestOptions({ 65 65 method: 'GET', 66 66 responseStyle: 'data', 67 67 url: '/pet/findByStatus', ··· 75 75 export const findPetsByTagsRequest = <ThrowOnError extends boolean = false>( 76 76 options: Options<FindPetsByTagsData, ThrowOnError>, 77 77 ): HttpRequest<unknown> => 78 - (options?.client ? options.client : _heyApiClient).requestOptions({ 78 + (options?.client ?? _heyApiClient).requestOptions({ 79 79 method: 'GET', 80 80 responseStyle: 'data', 81 81 url: '/pet/findByTags', ··· 89 89 export const deletePetRequest = <ThrowOnError extends boolean = false>( 90 90 options: Options<DeletePetData, ThrowOnError>, 91 91 ): HttpRequest<unknown> => 92 - (options?.client ? options.client : _heyApiClient).requestOptions({ 92 + (options?.client ?? _heyApiClient).requestOptions({ 93 93 method: 'DELETE', 94 94 responseStyle: 'data', 95 95 url: '/pet/{petId}', ··· 103 103 export const getPetByIdRequest = <ThrowOnError extends boolean = false>( 104 104 options: Options<GetPetByIdData, ThrowOnError>, 105 105 ): HttpRequest<unknown> => 106 - (options?.client ? options.client : _heyApiClient).requestOptions({ 106 + (options?.client ?? _heyApiClient).requestOptions({ 107 107 method: 'GET', 108 108 responseStyle: 'data', 109 109 url: '/pet/{petId}', ··· 117 117 export const updatePetWithFormRequest = <ThrowOnError extends boolean = false>( 118 118 options: Options<UpdatePetWithFormData, ThrowOnError>, 119 119 ): HttpRequest<unknown> => 120 - (options?.client ? options.client : _heyApiClient).requestOptions({ 120 + (options?.client ?? _heyApiClient).requestOptions({ 121 121 method: 'POST', 122 122 responseStyle: 'data', 123 123 url: '/pet/{petId}', ··· 131 131 export const uploadFileRequest = <ThrowOnError extends boolean = false>( 132 132 options: Options<UploadFileData, ThrowOnError>, 133 133 ): HttpRequest<unknown> => 134 - (options?.client ? options.client : _heyApiClient).requestOptions({ 134 + (options?.client ?? _heyApiClient).requestOptions({ 135 135 method: 'POST', 136 136 responseStyle: 'data', 137 137 url: '/pet/{petId}/uploadImage', ··· 145 145 export const getInventoryRequest = <ThrowOnError extends boolean = false>( 146 146 options?: Options<GetInventoryData, ThrowOnError>, 147 147 ): HttpRequest<unknown> => 148 - (options?.client ? options.client : _heyApiClient).requestOptions({ 148 + (options?.client ?? _heyApiClient).requestOptions({ 149 149 method: 'GET', 150 150 responseStyle: 'data', 151 151 url: '/store/inventory', ··· 159 159 export const placeOrderRequest = <ThrowOnError extends boolean = false>( 160 160 options?: Options<PlaceOrderData, ThrowOnError>, 161 161 ): HttpRequest<unknown> => 162 - (options?.client ? options.client : _heyApiClient).requestOptions({ 162 + (options?.client ?? _heyApiClient).requestOptions({ 163 163 method: 'POST', 164 164 responseStyle: 'data', 165 165 url: '/store/order', ··· 173 173 export const deleteOrderRequest = <ThrowOnError extends boolean = false>( 174 174 options: Options<DeleteOrderData, ThrowOnError>, 175 175 ): HttpRequest<unknown> => 176 - (options?.client ? options.client : _heyApiClient).requestOptions({ 176 + (options?.client ?? _heyApiClient).requestOptions({ 177 177 method: 'DELETE', 178 178 responseStyle: 'data', 179 179 url: '/store/order/{orderId}', ··· 187 187 export const getOrderByIdRequest = <ThrowOnError extends boolean = false>( 188 188 options: Options<GetOrderByIdData, ThrowOnError>, 189 189 ): HttpRequest<unknown> => 190 - (options?.client ? options.client : _heyApiClient).requestOptions({ 190 + (options?.client ?? _heyApiClient).requestOptions({ 191 191 method: 'GET', 192 192 responseStyle: 'data', 193 193 url: '/store/order/{orderId}', ··· 201 201 export const createUserRequest = <ThrowOnError extends boolean = false>( 202 202 options?: Options<CreateUserData, ThrowOnError>, 203 203 ): HttpRequest<unknown> => 204 - (options?.client ? options.client : _heyApiClient).requestOptions({ 204 + (options?.client ?? _heyApiClient).requestOptions({ 205 205 method: 'POST', 206 206 responseStyle: 'data', 207 207 url: '/user', ··· 217 217 >( 218 218 options?: Options<CreateUsersWithListInputData, ThrowOnError>, 219 219 ): HttpRequest<unknown> => 220 - (options?.client ? options.client : _heyApiClient).requestOptions({ 220 + (options?.client ?? _heyApiClient).requestOptions({ 221 221 method: 'POST', 222 222 responseStyle: 'data', 223 223 url: '/user/createWithList', ··· 231 231 export const loginUserRequest = <ThrowOnError extends boolean = false>( 232 232 options?: Options<LoginUserData, ThrowOnError>, 233 233 ): HttpRequest<unknown> => 234 - (options?.client ? options.client : _heyApiClient).requestOptions({ 234 + (options?.client ?? _heyApiClient).requestOptions({ 235 235 method: 'GET', 236 236 responseStyle: 'data', 237 237 url: '/user/login', ··· 245 245 export const logoutUserRequest = <ThrowOnError extends boolean = false>( 246 246 options?: Options<LogoutUserData, ThrowOnError>, 247 247 ): HttpRequest<unknown> => 248 - (options?.client ? options.client : _heyApiClient).requestOptions({ 248 + (options?.client ?? _heyApiClient).requestOptions({ 249 249 method: 'GET', 250 250 responseStyle: 'data', 251 251 url: '/user/logout', ··· 259 259 export const deleteUserRequest = <ThrowOnError extends boolean = false>( 260 260 options: Options<DeleteUserData, ThrowOnError>, 261 261 ): HttpRequest<unknown> => 262 - (options?.client ? options.client : _heyApiClient).requestOptions({ 262 + (options?.client ?? _heyApiClient).requestOptions({ 263 263 method: 'DELETE', 264 264 responseStyle: 'data', 265 265 url: '/user/{username}', ··· 273 273 export const getUserByNameRequest = <ThrowOnError extends boolean = false>( 274 274 options: Options<GetUserByNameData, ThrowOnError>, 275 275 ): HttpRequest<unknown> => 276 - (options?.client ? options.client : _heyApiClient).requestOptions({ 276 + (options?.client ?? _heyApiClient).requestOptions({ 277 277 method: 'GET', 278 278 responseStyle: 'data', 279 279 url: '/user/{username}', ··· 287 287 export const updateUserRequest = <ThrowOnError extends boolean = false>( 288 288 options: Options<UpdateUserData, ThrowOnError>, 289 289 ): HttpRequest<unknown> => 290 - (options?.client ? options.client : _heyApiClient).requestOptions({ 290 + (options?.client ?? _heyApiClient).requestOptions({ 291 291 method: 'PUT', 292 292 responseStyle: 'data', 293 293 url: '/user/{username}',
+4 -4
examples/openapi-ts-angular-resource/src/client/@angular/common/http/httpResource.gen.ts examples/openapi-ts-angular-common/src/client/@angular/common/http/resources.gen.ts
··· 59 59 updatePetWithFormRequest, 60 60 updateUserRequest, 61 61 uploadFileRequest, 62 - } from './httpRequests.gen'; 62 + } from './requests.gen'; 63 63 64 64 @Injectable({ 65 65 providedIn: 'root', 66 66 }) 67 - export class PetResources { 67 + export class PetServiceResources { 68 68 /** 69 69 * Add a new pet to the store. 70 70 * Add a new pet to the store. ··· 155 155 @Injectable({ 156 156 providedIn: 'root', 157 157 }) 158 - export class StoreResources { 158 + export class StoreServiceResources { 159 159 /** 160 160 * Returns pet inventories by status. 161 161 * Returns a map of status codes to quantities. ··· 206 206 @Injectable({ 207 207 providedIn: 'root', 208 208 }) 209 - export class UserResources { 209 + export class UserServiceResources { 210 210 /** 211 211 * Create user. 212 212 * This can only be done by the logged in user.
examples/openapi-ts-angular-resource/src/client/client.gen.ts examples/openapi-ts-angular-common/src/client/client.gen.ts
examples/openapi-ts-angular-resource/src/client/client/client.gen.ts examples/openapi-ts-angular-common/src/client/client/client.gen.ts
examples/openapi-ts-angular-resource/src/client/client/index.ts examples/openapi-ts-angular-common/src/client/client/index.ts
examples/openapi-ts-angular-resource/src/client/client/types.gen.ts examples/openapi-ts-angular-common/src/client/client/types.gen.ts
examples/openapi-ts-angular-resource/src/client/client/utils.gen.ts examples/openapi-ts-angular-common/src/client/client/utils.gen.ts
examples/openapi-ts-angular-resource/src/client/core/auth.gen.ts examples/openapi-ts-angular-common/src/client/core/auth.gen.ts
+2
examples/openapi-ts-angular-resource/src/client/core/bodySerializer.gen.ts examples/openapi-ts-angular-common/src/client/core/bodySerializer.gen.ts
··· 23 23 ): void => { 24 24 if (typeof value === 'string' || value instanceof Blob) { 25 25 data.append(key, value); 26 + } else if (value instanceof Date) { 27 + data.append(key, value.toISOString()); 26 28 } else { 27 29 data.append(key, JSON.stringify(value)); 28 30 }
examples/openapi-ts-angular-resource/src/client/core/params.gen.ts examples/openapi-ts-angular-common/src/client/core/params.gen.ts
examples/openapi-ts-angular-resource/src/client/core/pathSerializer.gen.ts examples/openapi-ts-angular-common/src/client/core/pathSerializer.gen.ts
examples/openapi-ts-angular-resource/src/client/core/types.gen.ts examples/openapi-ts-angular-common/src/client/core/types.gen.ts
-5
examples/openapi-ts-angular-resource/src/client/index.ts
··· 1 - // This file is auto-generated by @hey-api/openapi-ts 2 - export * from './@angular/common/http/httpRequests.gen'; 3 - export * from './@angular/common/http/httpResource.gen'; 4 - export * from './sdk.gen'; 5 - export * from './types.gen';
examples/openapi-ts-angular-resource/src/client/schemas.gen.ts examples/openapi-ts-angular-common/src/client/schemas.gen.ts
examples/openapi-ts-angular-resource/src/client/sdk.gen.ts examples/openapi-ts-angular-common/src/client/sdk.gen.ts
examples/openapi-ts-angular-resource/src/client/types.gen.ts examples/openapi-ts-angular-common/src/client/types.gen.ts
examples/openapi-ts-angular-resource/src/index.html examples/openapi-ts-angular-common/src/index.html
examples/openapi-ts-angular-resource/src/main.server.ts examples/openapi-ts-angular-common/src/main.server.ts
examples/openapi-ts-angular-resource/src/main.ts examples/openapi-ts-angular-common/src/main.ts
examples/openapi-ts-angular-resource/src/server.ts examples/openapi-ts-angular-common/src/server.ts
examples/openapi-ts-angular-resource/src/styles.css examples/openapi-ts-angular-common/src/styles.css
examples/openapi-ts-angular-resource/tsconfig.app.json examples/openapi-ts-angular-common/tsconfig.app.json
examples/openapi-ts-angular-resource/tsconfig.json examples/openapi-ts-angular-common/tsconfig.json
examples/openapi-ts-angular-resource/tsconfig.spec.json examples/openapi-ts-angular-common/tsconfig.spec.json
+1 -3
examples/openapi-ts-angular/openapi-ts.config.ts
··· 9 9 path: './src/client', 10 10 }, 11 11 plugins: [ 12 - { 13 - name: '@hey-api/client-angular', 14 - }, 12 + '@hey-api/client-angular', 15 13 '@hey-api/schemas', 16 14 { 17 15 asClass: true,
+2
examples/openapi-ts-angular/src/client/core/bodySerializer.gen.ts
··· 23 23 ): void => { 24 24 if (typeof value === 'string' || value instanceof Blob) { 25 25 data.append(key, value); 26 + } else if (value instanceof Date) { 27 + data.append(key, value.toISOString()); 26 28 } else { 27 29 data.append(key, JSON.stringify(value)); 28 30 }
+11 -4
packages/openapi-ts-tests/main/test/openapi-ts.config.ts
··· 40 40 path: path.resolve( 41 41 getSpecsPath(), 42 42 '3.1.x', 43 - // 'full.yaml', 44 - 'validators-circular-ref.json', 43 + 'full.yaml', 44 + // 'validators-circular-ref.json', 45 45 ), 46 46 // path: 'http://localhost:4000/', 47 47 // path: 'https://get.heyapi.dev/', ··· 127 127 { 128 128 // baseUrl: false, 129 129 // exportFromIndex: true, 130 - name: '@hey-api/client-fetch', 130 + // name: '@hey-api/client-fetch', 131 + name: '@hey-api/client-angular', 131 132 // name: 'legacy/angular', 132 133 // strictBaseUrl: true, 133 134 throwOnError: true, ··· 231 232 // infer: 'D{{name}}ZodType', 232 233 // }, 233 234 }, 234 - // exportFromIndex: true, 235 + exportFromIndex: true, 235 236 metadata: true, 236 237 name: 'zod', 237 238 // requests: { ··· 258 259 exportFromIndex: true, 259 260 // name: '@hey-api/schemas', 260 261 // type: 'json', 262 + }, 263 + { 264 + // httpRequest 265 + // httpResource 266 + exportFromIndex: true, 267 + name: '@angular/common', 261 268 }, 262 269 ], 263 270 // useOptions: false,
+2 -1
packages/openapi-ts/README.md
··· 282 282 ### Native Clients 283 283 284 284 - [`@hey-api/client-fetch`](https://heyapi.dev/openapi-ts/clients/fetch) 285 + - [`@hey-api/client-angular`](https://heyapi.dev/openapi-ts/clients/angular) 285 286 - [`@hey-api/client-axios`](https://heyapi.dev/openapi-ts/clients/axios) 286 287 - [`@hey-api/client-next`](https://heyapi.dev/openapi-ts/clients/next-js) 287 288 - [`@hey-api/client-nuxt`](https://heyapi.dev/openapi-ts/clients/nuxt) ··· 290 291 291 292 The following clients are planned but not in development yet. You can help us prioritize them by voting on [GitHub](https://github.com/hey-api/openapi-ts/labels/RSVP%20%F0%9F%91%8D%F0%9F%91%8E). 292 293 293 - - [`@hey-api/client-angular`](https://heyapi.dev/openapi-ts/clients/angular) 294 294 - [`@hey-api/client-effect`](https://heyapi.dev/openapi-ts/clients/effect) 295 295 296 296 Don't see your client? [Build your own](https://heyapi.dev/openapi-ts/clients/custom) or let us know your interest by [opening an issue](https://github.com/hey-api/openapi-ts/issues). ··· 308 308 - [`@tanstack/solid-query`](https://heyapi.dev/openapi-ts/plugins/tanstack-query) 309 309 - [`@tanstack/svelte-query`](https://heyapi.dev/openapi-ts/plugins/tanstack-query) 310 310 - [`@tanstack/vue-query`](https://heyapi.dev/openapi-ts/plugins/tanstack-query) 311 + - [`@angular/common`](https://heyapi.dev/openapi-ts/plugins/angular) 311 312 - [`fastify`](https://heyapi.dev/openapi-ts/plugins/fastify) 312 313 - [`valibot`](https://heyapi.dev/openapi-ts/plugins/valibot) 313 314 - [`zod`](https://heyapi.dev/openapi-ts/plugins/zod)
+92 -82
packages/openapi-ts/src/plugins/@angular/common/companions/angularHttpRequestsCompanionPluginHandler.ts packages/openapi-ts/src/plugins/@angular/common/httpRequests.ts
··· 1 - import { tsc } from '../../../../tsc'; 2 - import { stringCase } from '../../../../utils/stringCase'; 3 - import { clientId } from '../../../@hey-api/client-core/utils'; 4 - import { sdkId } from '../../../@hey-api/sdk/constants'; 5 - import { operationClasses } from '../../../@hey-api/sdk/operation'; 6 - import { typesId } from '../../../@hey-api/typescript/ref'; 1 + import type ts from 'typescript'; 2 + 3 + import type { GeneratedFile } from '../../../generate/file'; 4 + import type { IR } from '../../../ir/types'; 5 + import { buildName } from '../../../openApi/shared/utils/name'; 6 + import { tsc } from '../../../tsc'; 7 + import { stringCase } from '../../../utils/stringCase'; 8 + import { clientId } from '../../@hey-api/client-core/utils'; 9 + import { sdkId } from '../../@hey-api/sdk/constants'; 10 + import { operationClasses } from '../../@hey-api/sdk/operation'; 11 + import { typesId } from '../../@hey-api/typescript/ref'; 7 12 import { 8 13 createOperationComment, 9 14 isOperationOptionsRequired, 10 - } from '../../../shared/utils/operation'; 11 - import type { AngularCommonPlugin } from '../types'; 12 - 13 - export const REQUEST_APIS_SUFFIX = '/http/httpRequests'; 14 - 15 - export const angularHttpRequestsCompanionPluginHandler: AngularCommonPlugin['Handler'] = 16 - ({ plugin }) => { 17 - const sdkPlugin = plugin.getPlugin('@hey-api/sdk'); 18 - 19 - const file = plugin.createFile({ 20 - exportFromIndex: true, 21 - id: plugin.name + REQUEST_APIS_SUFFIX, 22 - path: plugin.output + REQUEST_APIS_SUFFIX, 23 - }); 24 - 25 - if (plugin.config.httpRequest?.asClass) { 26 - file.import({ 27 - module: '@angular/core', 28 - name: 'Injectable', 29 - }); 30 - } 31 - 32 - file.import({ 33 - module: '@angular/common/http', 34 - name: 'HttpRequest', 35 - }); 36 - 37 - file.import({ 38 - module: file.relativePathToFile({ 39 - context: plugin.context, 40 - id: sdkId, 41 - }), 42 - name: 'Options', 43 - }); 44 - 45 - if (plugin.config.httpRequest?.asClass) { 46 - generateAngularClassRequests({ file, plugin, sdkPlugin }); 47 - } else { 48 - generateAngularFunctionRequests({ file, plugin }); 49 - } 50 - }; 15 + } from '../../shared/utils/operation'; 16 + import { REQUEST_APIS_SUFFIX } from './constants'; 17 + import type { AngularCommonPlugin } from './types'; 51 18 52 19 interface AngularRequestClassEntry { 53 20 className: string; 54 21 classes: Set<string>; 55 22 methods: Set<string>; 56 - nodes: Array<any>; 23 + nodes: Array<ts.ClassElement>; 57 24 root: boolean; 58 25 } 59 26 60 27 const generateAngularClassRequests = ({ 61 28 file, 62 29 plugin, 63 - sdkPlugin, 64 30 }: { 65 - file: any; 31 + file: GeneratedFile; 66 32 plugin: AngularCommonPlugin['Instance']; 67 - sdkPlugin: any; 68 33 }) => { 69 34 const requestClasses = new Map<string, AngularRequestClassEntry>(); 70 35 const generatedClasses = new Set<string>(); 36 + 37 + const sdkPlugin = plugin.getPlugin('@hey-api/sdk')!; 71 38 72 39 // Iterate through operations to build class structure 73 40 plugin.forEach('operation', ({ operation }) => { ··· 110 77 111 78 // Generate the request method name with "Request" suffix 112 79 const requestMethodName = 113 - plugin.config.httpRequest!.methodNameBuilder!(operation); 80 + plugin.config.httpRequests.methodNameBuilder(operation); 114 81 115 82 // Avoid duplicate methods 116 83 if (currentClass.methods.has(requestMethodName)) { ··· 129 96 if (!currentClass.nodes.length) { 130 97 currentClass.nodes.push(methodNode); 131 98 } else { 99 + // @ts-expect-error 132 100 currentClass.nodes.push(tsc.identifier({ text: '\n' }), methodNode); 133 101 } 134 102 ··· 155 123 initializer: tsc.newExpression({ 156 124 argumentsArray: [], 157 125 expression: tsc.identifier({ 158 - text: plugin.config.httpRequest!.classNameBuilder!( 159 - childClass.className, 160 - ), 126 + text: buildName({ 127 + config: { 128 + case: 'preserve', 129 + name: plugin.config.httpRequests.classNameBuilder, 130 + }, 131 + name: childClass.className, 132 + }), 161 133 }), 162 134 }), 163 135 name: stringCase({ ··· 181 153 } 182 154 : undefined, 183 155 exportClass: currentClass.root, 184 - name: plugin.config.httpRequest!.classNameBuilder!( 185 - currentClass.className, 186 - ), 156 + name: buildName({ 157 + config: { 158 + case: 'preserve', 159 + name: plugin.config.httpRequests.classNameBuilder, 160 + }, 161 + name: currentClass.className, 162 + }), 187 163 nodes: currentClass.nodes, 188 164 }); 189 165 ··· 200 176 file, 201 177 plugin, 202 178 }: { 203 - file: any; 179 + file: GeneratedFile; 204 180 plugin: AngularCommonPlugin['Instance']; 205 181 }) => { 206 182 plugin.forEach('operation', ({ operation }) => { ··· 211 187 212 188 // Generate function name with "Request" suffix 213 189 const functionName = 214 - plugin.config.httpRequest!.methodNameBuilder!(operation); 190 + plugin.config.httpRequests.methodNameBuilder(operation); 215 191 216 192 const node = generateAngularRequestFunction({ 217 193 file, ··· 230 206 operation, 231 207 plugin, 232 208 }: { 233 - file: any; 234 - operation: any; 235 - plugin: any; 209 + file: GeneratedFile; 210 + operation: IR.OperationObject; 211 + plugin: AngularCommonPlugin['Instance']; 236 212 }) => { 237 - // Import the client and use requestOptions instead of HTTP methods 238 - const clientImport = file.import({ 213 + // TODO: client might not be always defined 214 + const heyApiClient = file.import({ 239 215 alias: '_heyApiClient', 240 216 module: file.relativePathToFile({ 241 217 context: plugin.context, ··· 244 220 name: 'client', 245 221 }); 246 222 223 + const optionsClient = tsc.propertyAccessExpression({ 224 + expression: tsc.identifier({ text: 'options' }), 225 + isOptional: true, 226 + name: 'client', 227 + }); 228 + 247 229 return tsc.callExpression({ 248 230 functionName: tsc.propertyAccessExpression({ 249 - expression: tsc.conditionalExpression({ 250 - condition: tsc.propertyAccessExpression({ 251 - expression: tsc.identifier({ text: 'options' }), 252 - isOptional: true, 253 - name: 'client', 254 - }), 255 - whenFalse: tsc.identifier({ text: clientImport.name }), 256 - whenTrue: tsc.propertyAccessExpression({ 257 - expression: tsc.identifier({ text: 'options' }), 258 - name: 'client', 259 - }), 231 + expression: tsc.binaryExpression({ 232 + left: optionsClient, 233 + operator: '??', 234 + right: tsc.identifier({ text: heyApiClient.name }), 260 235 }), 261 236 name: 'requestOptions', 262 237 }), ··· 293 268 operation, 294 269 plugin, 295 270 }: { 296 - file: any; 271 + file: GeneratedFile; 297 272 isRequiredOptions: boolean; 298 273 methodName: string; 299 - operation: any; 300 - plugin: any; 274 + operation: IR.OperationObject; 275 + plugin: AngularCommonPlugin['Instance']; 301 276 }) => { 302 277 // Import operation data type 303 278 const pluginTypeScript = plugin.getPlugin('@hey-api/typescript')!; ··· 348 323 operation, 349 324 plugin, 350 325 }: { 351 - file: any; 326 + file: GeneratedFile; 352 327 functionName: string; 353 328 isRequiredOptions: boolean; 354 - operation: any; 355 - plugin: any; 329 + operation: IR.OperationObject; 330 + plugin: AngularCommonPlugin['Instance']; 356 331 }) => { 357 332 const pluginTypeScript = plugin.getPlugin('@hey-api/typescript')!; 358 333 const fileTypeScript = plugin.context.file({ id: typesId })!; ··· 396 371 name: functionName, 397 372 }); 398 373 }; 374 + 375 + export const createHttpRequests: AngularCommonPlugin['Handler'] = ({ 376 + plugin, 377 + }) => { 378 + const file = plugin.createFile({ 379 + id: `${plugin.name}${REQUEST_APIS_SUFFIX}`, 380 + path: `${plugin.output}${REQUEST_APIS_SUFFIX}`, 381 + }); 382 + 383 + if (plugin.config.httpRequests.asClass) { 384 + file.import({ 385 + module: '@angular/core', 386 + name: 'Injectable', 387 + }); 388 + } 389 + 390 + file.import({ 391 + module: '@angular/common/http', 392 + name: 'HttpRequest', 393 + }); 394 + 395 + file.import({ 396 + module: file.relativePathToFile({ 397 + context: plugin.context, 398 + id: sdkId, 399 + }), 400 + name: 'Options', 401 + }); 402 + 403 + if (plugin.config.httpRequests.asClass) { 404 + generateAngularClassRequests({ file, plugin }); 405 + } else { 406 + generateAngularFunctionRequests({ file, plugin }); 407 + } 408 + };
+101 -96
packages/openapi-ts/src/plugins/@angular/common/companions/angularHttpResourceCompanionPluginHandler.ts packages/openapi-ts/src/plugins/@angular/common/httpResources.ts
··· 1 - import { tsc } from '../../../../tsc'; 2 - import { stringCase } from '../../../../utils/stringCase'; 3 - import { sdkId } from '../../../@hey-api/sdk/constants'; 4 - import { operationClasses } from '../../../@hey-api/sdk/operation'; 5 - import { typesId } from '../../../@hey-api/typescript/ref'; 1 + import type ts from 'typescript'; 2 + 3 + import type { GeneratedFile } from '../../../generate/file'; 4 + import type { IR } from '../../../ir/types'; 5 + import { buildName } from '../../../openApi/shared/utils/name'; 6 + import { tsc } from '../../../tsc'; 7 + import { stringCase } from '../../../utils/stringCase'; 8 + import { sdkId } from '../../@hey-api/sdk/constants'; 9 + import { operationClasses } from '../../@hey-api/sdk/operation'; 10 + import { typesId } from '../../@hey-api/typescript/ref'; 6 11 import { 7 12 createOperationComment, 8 13 isOperationOptionsRequired, 9 - } from '../../../shared/utils/operation'; 10 - import type { AngularCommonPlugin } from '../types'; 11 - import { REQUEST_APIS_SUFFIX } from './angularHttpRequestsCompanionPluginHandler'; 12 - 13 - export const RESOURCE_APIS_SUFFIX = '/http/httpResource'; 14 - 15 - export const angularHttpResourceCompanionPluginHandler: AngularCommonPlugin['Handler'] = 16 - ({ plugin }) => { 17 - const sdkPlugin = plugin.getPlugin('@hey-api/sdk'); 18 - 19 - const file = plugin.createFile({ 20 - exportFromIndex: true, 21 - id: plugin.name + RESOURCE_APIS_SUFFIX, 22 - path: plugin.output + RESOURCE_APIS_SUFFIX, 23 - }); 24 - 25 - if (plugin.config.httpResource?.asClass) { 26 - file.import({ 27 - module: '@angular/core', 28 - name: 'Injectable', 29 - }); 30 - } 31 - 32 - if (plugin.config.httpRequest?.asClass) { 33 - file.import({ 34 - module: '@angular/core', 35 - name: 'inject', 36 - }); 37 - } 38 - 39 - file.import({ 40 - module: '@angular/common/http', 41 - name: 'httpResource', 42 - }); 43 - 44 - file.import({ 45 - module: file.relativePathToFile({ 46 - context: plugin.context, 47 - id: sdkId, 48 - }), 49 - name: 'Options', 50 - }); 51 - 52 - if (plugin.config.httpResource!.asClass) { 53 - generateAngularClassServices({ file, plugin, sdkPlugin }); 54 - } else { 55 - generateAngularFunctionServices({ file, plugin, sdkPlugin }); 56 - } 57 - }; 14 + } from '../../shared/utils/operation'; 15 + import { REQUEST_APIS_SUFFIX, RESOURCE_APIS_SUFFIX } from './constants'; 16 + import type { AngularCommonPlugin } from './types'; 58 17 59 18 interface AngularServiceClassEntry { 60 19 className: string; 61 20 classes: Set<string>; 62 21 methods: Set<string>; 63 - nodes: Array<any>; 22 + nodes: Array<ts.ClassElement>; 64 23 root: boolean; 65 24 } 66 25 67 26 const generateAngularClassServices = ({ 68 27 file, 69 28 plugin, 70 - sdkPlugin, 71 29 }: { 72 - file: any; 30 + file: GeneratedFile; 73 31 plugin: AngularCommonPlugin['Instance']; 74 - sdkPlugin: any; 75 32 }) => { 76 33 const serviceClasses = new Map<string, AngularServiceClassEntry>(); 77 34 const generatedClasses = new Set<string>(); 35 + 36 + const sdkPlugin = plugin.getPlugin('@hey-api/sdk')!; 78 37 79 38 // Iterate through operations to build class structure 80 39 plugin.forEach('operation', ({ operation }) => { ··· 117 76 118 77 // Generate the resource method name 119 78 const resourceMethodName = 120 - plugin.config.httpResource!.methodNameBuilder!(operation); 79 + plugin.config.httpResources.methodNameBuilder(operation); 121 80 122 81 // Avoid duplicate methods 123 82 if (currentClass.methods.has(resourceMethodName)) { ··· 131 90 methodName: resourceMethodName, 132 91 operation, 133 92 plugin, 134 - sdkPlugin, 135 93 }); 136 94 137 95 if (!currentClass.nodes.length) { 138 96 currentClass.nodes.push(methodNode); 139 97 } else { 98 + // @ts-expect-error 140 99 currentClass.nodes.push(tsc.identifier({ text: '\n' }), methodNode); 141 100 } 142 101 ··· 163 122 initializer: tsc.newExpression({ 164 123 argumentsArray: [], 165 124 expression: tsc.identifier({ 166 - text: plugin.config.httpResource!.classNameBuilder!( 167 - childClass.className, 168 - ), 125 + text: buildName({ 126 + config: { 127 + case: 'preserve', 128 + name: plugin.config.httpResources.classNameBuilder, 129 + }, 130 + name: childClass.className, 131 + }), 169 132 }), 170 133 }), 171 134 name: stringCase({ ··· 189 152 } 190 153 : undefined, 191 154 exportClass: currentClass.root, 192 - name: plugin.config.httpResource!.classNameBuilder!( 193 - currentClass.className, 194 - ), 155 + name: buildName({ 156 + config: { 157 + case: 'preserve', 158 + name: plugin.config.httpResources.classNameBuilder, 159 + }, 160 + name: currentClass.className, 161 + }), 195 162 nodes: currentClass.nodes, 196 163 }); 197 164 ··· 207 174 const generateAngularFunctionServices = ({ 208 175 file, 209 176 plugin, 210 - sdkPlugin, 211 177 }: { 212 - file: any; 178 + file: GeneratedFile; 213 179 plugin: AngularCommonPlugin['Instance']; 214 - sdkPlugin: any; 215 180 }) => { 216 181 plugin.forEach('operation', ({ operation }) => { 217 182 const isRequiredOptions = isOperationOptionsRequired({ ··· 221 186 222 187 const node = generateAngularResourceFunction({ 223 188 file, 224 - functionName: plugin.config.httpResource!.methodNameBuilder!(operation), 189 + functionName: plugin.config.httpResources.methodNameBuilder(operation), 225 190 isRequiredOptions, 226 191 operation, 227 192 plugin, 228 - sdkPlugin, 229 193 }); 230 194 231 195 file.add(node); ··· 238 202 operation, 239 203 plugin, 240 204 responseTypeName, 241 - sdkPlugin, 242 205 }: { 243 - file: any; 206 + file: GeneratedFile; 244 207 isRequiredOptions: boolean; 245 - operation: any; 246 - plugin: any; 208 + operation: IR.OperationObject; 209 + plugin: AngularCommonPlugin['Instance']; 247 210 responseTypeName: string; 248 - sdkPlugin: any; 249 211 }) => { 212 + const sdkPlugin = plugin.getPlugin('@hey-api/sdk')!; 213 + 250 214 // Check if httpRequest is configured to use classes 251 - const useRequestClasses = plugin.config.httpRequest?.asClass; 215 + const useRequestClasses = plugin.config.httpRequests.asClass; 252 216 let requestFunctionCall; 253 217 254 218 // Create the options call expression based on whether options are required ··· 277 241 const firstEntry = Array.from(classes.values())[0]; 278 242 if (firstEntry) { 279 243 // Import the root class from HTTP requests 280 - const rootClassName = firstEntry.path[0]; 281 - const requestClassName = 282 - plugin.config.httpRequest!.classNameBuilder!(rootClassName); 244 + const rootClassName = firstEntry.path[0]!; 245 + const requestClassName = buildName({ 246 + config: { 247 + case: 'preserve', 248 + name: plugin.config.httpRequests.classNameBuilder, 249 + }, 250 + name: rootClassName, 251 + }); 283 252 284 253 // Build the method access path using inject 285 - let methodAccess: any = tsc.callExpression({ 254 + let methodAccess: ts.Expression = tsc.callExpression({ 286 255 functionName: 'inject', 287 256 parameters: [tsc.identifier({ text: requestClassName })], 288 257 }); ··· 303 272 304 273 // Add the final method name with "Request" suffix 305 274 const requestMethodName = 306 - plugin.config.httpRequest!.methodNameBuilder!(operation); 275 + plugin.config.httpRequests.methodNameBuilder(operation); 307 276 methodAccess = tsc.propertyAccessExpression({ 308 277 expression: methodAccess, 309 278 name: requestMethodName, ··· 317 286 } else { 318 287 // For function-based request methods, import and call the function directly 319 288 const requestFunctionName = 320 - plugin.config.httpRequest!.methodNameBuilder!(operation); 289 + plugin.config.httpRequests.methodNameBuilder(operation); 321 290 322 291 const requestImport = file.import({ 323 292 module: file.relativePathToFile({ 324 293 context: plugin.context, 325 - id: plugin.name + REQUEST_APIS_SUFFIX, 294 + id: `${plugin.name}${REQUEST_APIS_SUFFIX}`, 326 295 }), 327 296 name: requestFunctionName, 328 297 }); ··· 355 324 methodName, 356 325 operation, 357 326 plugin, 358 - sdkPlugin, 359 327 }: { 360 - file: any; 328 + file: GeneratedFile; 361 329 isRequiredOptions: boolean; 362 330 methodName: string; 363 - operation: any; 364 - plugin: any; 365 - sdkPlugin: any; 331 + operation: IR.OperationObject; 332 + plugin: AngularCommonPlugin['Instance']; 366 333 }) => { 367 334 // Import operation data type 368 335 const pluginTypeScript = plugin.getPlugin('@hey-api/typescript')!; ··· 405 372 operation, 406 373 plugin, 407 374 responseTypeName: responseType.name || 'unknown', 408 - sdkPlugin, 409 375 }), 410 376 }), 411 377 ], ··· 425 391 isRequiredOptions, 426 392 operation, 427 393 plugin, 428 - sdkPlugin, 429 394 }: { 430 - file: any; 395 + file: GeneratedFile; 431 396 functionName: string; 432 397 isRequiredOptions: boolean; 433 - operation: any; 434 - plugin: any; 435 - sdkPlugin: any; 398 + operation: IR.OperationObject; 399 + plugin: AngularCommonPlugin['Instance']; 436 400 }) => { 437 401 const pluginTypeScript = plugin.getPlugin('@hey-api/typescript')!; 438 402 const fileTypeScript = plugin.context.file({ id: typesId })!; ··· 472 436 operation, 473 437 plugin, 474 438 responseTypeName: responseType.name || 'unknown', 475 - sdkPlugin, 476 439 }), 477 440 }), 478 441 ], ··· 487 450 name: functionName, 488 451 }); 489 452 }; 453 + 454 + export const createHttpResources: AngularCommonPlugin['Handler'] = ({ 455 + plugin, 456 + }) => { 457 + const file = plugin.createFile({ 458 + id: `${plugin.name}${RESOURCE_APIS_SUFFIX}`, 459 + path: `${plugin.output}${RESOURCE_APIS_SUFFIX}`, 460 + }); 461 + 462 + if (plugin.config.httpResources.asClass) { 463 + file.import({ 464 + module: '@angular/core', 465 + name: 'Injectable', 466 + }); 467 + } 468 + 469 + if (plugin.config.httpRequests.asClass) { 470 + file.import({ 471 + module: '@angular/core', 472 + name: 'inject', 473 + }); 474 + } 475 + 476 + file.import({ 477 + module: '@angular/common/http', 478 + name: 'httpResource', 479 + }); 480 + 481 + file.import({ 482 + module: file.relativePathToFile({ 483 + context: plugin.context, 484 + id: sdkId, 485 + }), 486 + name: 'Options', 487 + }); 488 + 489 + if (plugin.config.httpResources.asClass) { 490 + generateAngularClassServices({ file, plugin }); 491 + } else { 492 + generateAngularFunctionServices({ file, plugin }); 493 + } 494 + };
+34 -27
packages/openapi-ts/src/plugins/@angular/common/config.ts
··· 3 3 import type { AngularCommonPlugin } from './types'; 4 4 5 5 export const defaultConfig: AngularCommonPlugin['Config'] = { 6 - config: {}, 6 + config: { 7 + exportFromIndex: false, 8 + }, 7 9 dependencies: ['@hey-api/client-angular', '@hey-api/sdk'], 8 10 handler, 9 11 name: '@angular/common', 10 12 output: '@angular/common', 11 - resolveConfig(plugin) { 12 - plugin.config.httpResource = { 13 - asClass: false, 14 - classNameBuilder(className) { 15 - return className + 'Resources'; 13 + resolveConfig: (plugin, context) => { 14 + plugin.config.httpRequests = context.valueToObject({ 15 + defaultValue: { 16 + asClass: false, 17 + classNameBuilder: '{{name}}Requests', 18 + enabled: true, 19 + }, 20 + mappers: { 21 + boolean: (enabled) => ({ enabled }), 16 22 }, 17 - enabled: false, 18 - methodNameBuilder(operation) { 19 - if (plugin.config.httpResource?.asClass) { 20 - return String(operation.id); 21 - } 23 + value: plugin.config.httpRequests, 24 + }); 25 + 26 + if (!plugin.config.httpRequests.methodNameBuilder) { 27 + const { asClass } = plugin.config.httpRequests; 28 + plugin.config.httpRequests.methodNameBuilder = (operation) => 29 + asClass ? String(operation.id) : `${String(operation.id)}Request`; 30 + } 22 31 23 - return String(operation.id) + 'Resource'; 32 + plugin.config.httpResources = context.valueToObject({ 33 + defaultValue: { 34 + asClass: false, 35 + classNameBuilder: '{{name}}Resources', 36 + enabled: true, 24 37 }, 25 - ...plugin.config.httpResource, 26 - }; 27 - 28 - plugin.config.httpRequest = { 29 - asClass: false, 30 - classNameBuilder(className) { 31 - return className + 'Requests'; 38 + mappers: { 39 + boolean: (enabled) => ({ enabled }), 32 40 }, 33 - methodNameBuilder(operation) { 34 - if (plugin.config.httpRequest?.asClass) { 35 - return String(operation.id); 36 - } 41 + value: plugin.config.httpResources, 42 + }); 37 43 38 - return String(operation.id) + 'Request'; 39 - }, 40 - ...plugin.config.httpRequest, 41 - }; 44 + if (!plugin.config.httpResources.methodNameBuilder) { 45 + const { asClass } = plugin.config.httpResources; 46 + plugin.config.httpResources.methodNameBuilder = (operation) => 47 + asClass ? String(operation.id) : `${String(operation.id)}Resource`; 48 + } 42 49 }, 43 50 }; 44 51
+2
packages/openapi-ts/src/plugins/@angular/common/constants.ts
··· 1 + export const REQUEST_APIS_SUFFIX = '/http/requests'; 2 + export const RESOURCE_APIS_SUFFIX = '/http/resources';
+8 -6
packages/openapi-ts/src/plugins/@angular/common/plugin.ts
··· 1 - import { angularHttpRequestsCompanionPluginHandler } from './companions/angularHttpRequestsCompanionPluginHandler'; 2 - import { angularHttpResourceCompanionPluginHandler } from './companions/angularHttpResourceCompanionPluginHandler'; 1 + import { createHttpRequests } from './httpRequests'; 2 + import { createHttpResources } from './httpResources'; 3 3 import type { AngularCommonPlugin } from './types'; 4 4 5 - export const handler: AngularCommonPlugin['Handler'] = (args) => { 6 - angularHttpRequestsCompanionPluginHandler(args); 5 + export const handler: AngularCommonPlugin['Handler'] = ({ plugin }) => { 6 + if (plugin.config.httpRequests.enabled) { 7 + createHttpRequests({ plugin }); 8 + } 7 9 8 - if (args.plugin.config.httpResource?.enabled) { 9 - angularHttpResourceCompanionPluginHandler(args); 10 + if (plugin.config.httpResources.enabled) { 11 + createHttpResources({ plugin }); 10 12 } 11 13 };
+124 -39
packages/openapi-ts/src/plugins/@angular/common/types.d.ts
··· 1 - import type { Operation } from '../../../types/client'; 1 + import type { StringName } from '../../../types/case'; 2 2 import type { DefinePlugin, Plugin } from '../../types'; 3 3 4 - export type AngularHttpResourceOptions = { 4 + export type UserConfig = Plugin.Name<'@angular/common'> & { 5 5 /** 6 - * Whether to generate the resource as a class. 6 + * Should the exports from the generated files be re-exported in the index 7 + * barrel file? 8 + * 7 9 * @default false 8 10 */ 9 - asClass?: boolean; 10 - 11 + exportFromIndex?: boolean; 11 12 /** 12 - * Builds the class name for the generated resource. 13 - * By default, the class name is suffixed with "Resources". 13 + * Options for generating HTTP Request instances. 14 + * 15 + * @default true 14 16 */ 15 - classNameBuilder?: (className: string) => string; 16 - 17 + httpRequests?: 18 + | boolean 19 + | { 20 + /** 21 + * Whether to generate the resource as a class. 22 + * 23 + * @default false 24 + */ 25 + asClass?: boolean; 26 + /** 27 + * Builds the class name for the generated resource. 28 + * By default, the class name is suffixed with "Resources". 29 + */ 30 + classNameBuilder?: StringName; 31 + /** 32 + * Whether or not to create HTTP Request instances. 33 + * 34 + * @default true 35 + */ 36 + enabled?: boolean; 37 + /** 38 + * Builds the method name for the generated resource. 39 + * 40 + * By default, the operation id is used, if `asClass` is false, the method is also suffixed with "Resource". 41 + */ 42 + methodNameBuilder?: (operation: IR.OperationObject) => string; 43 + }; 17 44 /** 18 - * Wether or not to create http resource APIs. 45 + * Options for generating HTTP resource APIs. 46 + * 47 + * @default true 19 48 */ 20 - enabled: boolean; 21 - 49 + httpResources?: 50 + | boolean 51 + | { 52 + /** 53 + * Whether to generate the resource as a class. 54 + * @default false 55 + */ 56 + asClass?: boolean; 57 + /** 58 + * Builds the class name for the generated resource. 59 + * By default, the class name is suffixed with "Resources". 60 + */ 61 + classNameBuilder?: StringName; 62 + /** 63 + * Whether or not to create HTTP resource APIs. 64 + * 65 + * @default true 66 + */ 67 + enabled?: boolean; 68 + /** 69 + * Builds the method name for the generated resource. 70 + * 71 + * By default, the operation id is used, if `asClass` is false, the method is also suffixed with "Resource". 72 + */ 73 + methodNameBuilder?: (operation: IR.OperationObject) => string; 74 + }; 22 75 /** 23 - * Builds the method name for the generated resource. 24 - * By default, the operation id is used, if `asClass` is false, the method is also suffixed with "Resource". 76 + * Name of the generated file. 77 + * 78 + * @default '@angular/common' 25 79 */ 26 - methodNameBuilder?: (operation: IR.OperationObject | Operation) => string; 80 + output?: string; 27 81 }; 28 82 29 - export type AngularHttpRequestOptions = { 83 + export type Config = Plugin.Name<'@angular/common'> & { 30 84 /** 31 - * Whether to generate the resource as a class. 85 + * Should the exports from the generated files be re-exported in the index 86 + * barrel file? 87 + * 32 88 * @default false 33 89 */ 34 - asClass?: boolean; 35 - 36 - /** 37 - * Builds the class name for the generated resource. 38 - * By default, the class name is suffixed with "Resources". 39 - */ 40 - classNameBuilder?: (className: string) => string; 41 - 42 - /** 43 - * Builds the method name for the generated resource. 44 - * By default, the operation id is used, if `asClass` is false, the method is also suffixed with "Resource". 45 - */ 46 - methodNameBuilder?: (operation: IR.OperationObject | Operation) => string; 47 - }; 48 - 49 - export type UserConfig = Plugin.Name<'@angular/common'> & { 90 + exportFromIndex: boolean; 50 91 /** 51 92 * Options for generating HTTP Request instances. 52 93 */ 53 - httpRequest?: AngularHttpRequestOptions; 54 - 94 + httpRequests: { 95 + /** 96 + * Whether to generate the resource as a class. 97 + * 98 + * @default false 99 + */ 100 + asClass: boolean; 101 + /** 102 + * Builds the class name for the generated resource. 103 + * By default, the class name is suffixed with "Resources". 104 + */ 105 + classNameBuilder: StringName; 106 + /** 107 + * Whether or not to create HTTP Request instances. 108 + * 109 + * @default true 110 + */ 111 + enabled: boolean; 112 + /** 113 + * Builds the method name for the generated resource. 114 + * By default, the operation id is used, if `asClass` is false, the method is also suffixed with "Resource". 115 + */ 116 + methodNameBuilder: (operation: IR.OperationObject) => string; 117 + }; 55 118 /** 56 119 * Options for generating HTTP resource APIs. 57 120 */ 58 - httpResource?: AngularHttpResourceOptions; 59 - 121 + httpResources: { 122 + /** 123 + * Whether to generate the resource as a class. 124 + * 125 + * @default false 126 + */ 127 + asClass: boolean; 128 + /** 129 + * Builds the class name for the generated resource. 130 + * By default, the class name is suffixed with "Resources". 131 + */ 132 + classNameBuilder: StringName; 133 + /** 134 + * Whether or not to create HTTP resource APIs. 135 + * 136 + * @default true 137 + */ 138 + enabled: boolean; 139 + /** 140 + * Builds the method name for the generated resource. 141 + * By default, the operation id is used, if `asClass` is false, the method is also suffixed with "Resource". 142 + */ 143 + methodNameBuilder: (operation: IR.OperationObject) => string; 144 + }; 60 145 /** 61 146 * Name of the generated file. 62 147 * 63 148 * @default '@angular/common' 64 149 */ 65 - output?: string; 150 + output: string; 66 151 }; 67 152 68 - export type AngularCommonPlugin = DefinePlugin<UserConfig, UserConfig>; 153 + export type AngularCommonPlugin = DefinePlugin<UserConfig, Config>;
+1 -1
pnpm-lock.yaml
··· 203 203 specifier: 5.8.3 204 204 version: 5.8.3 205 205 206 - examples/openapi-ts-angular-resource: 206 + examples/openapi-ts-angular-common: 207 207 dependencies: 208 208 '@angular/common': 209 209 specifier: 19.2.0