Description
Description
I have generated a API client based on a pretty large OpenAPI specification file (JSON format) when I am trying to call one of the endpoints via its operation identifier. I am having the issue that when I call clientsSearchPost
it sends a request via the fetch
-client with GET
instead of POST
.
The generated code does call post
-function of the client but somehow it ends up being a GET
which causes the request to fail with 404 as there is no GET
counterpart of this endpoint.
Reproducible example or configuration
/** @type {import('@hey-api/openapi-ts').UserConfig} */
import { defaultPlugins } from '@hey-api/openapi-ts';
console.log('defaultPlugins:', defaultPlugins)
export default {
input: '../../specs/api',
output: {
clean: true,
indexFile: true,
path: 'src/client',
},
plugins: [
'@hey-api/client-fetch',
{
bundle: true,
},
'@hey-api/schemas',
{
dates: true,
name: '@hey-api/transformers',
},
{
enums: 'javascript',
name: '@hey-api/typescript',
},
{
name: '@hey-api/sdk',
asClass: true,
transformer: true,
}
],
};
The generated code for the earlier mentioned operation looks like:
return (options.client ?? _heyApiClient).post<ClientsSearchPostResponse, ClientsSearchPostError, ThrowOnError>({
Could it be that the interceptors are affecting the request method? I am using a request and response interceptor to support the fetching of OAuth2 client credentials tokens:
const clientConfig: HeyApiConfig = createHeyApiConfig({
baseUrl: this.baseUrl,
throwOnError: false,
});
this.apiClient = createHeyApiClient(clientConfig);
this.apiClient.interceptors.request.use(async (request: Request) => {
await this.ensureValidToken();
const newHeaders = new Headers(request.headers);
newHeaders.set('x-api-version', this.pinnedApiVersion);
if (this.currentToken) {
newHeaders.set('Authorization', `Bearer ${this.currentToken}`);
}
return new Request(request.url, {
...request,
headers: newHeaders
});
});
this.apiClient.interceptors.response.use(async (responseOrError: Response | any) => {
if (responseOrError instanceof Response) {
const response = responseOrError as Response;
if (response.status === 401 && this.tokenConfig) {
console.log('Received 401 (in success path), attempting to refresh token...');
this.currentToken = undefined;
this.tokenExpiry = undefined;
try {
await this.ensureValidToken();
console.warn('Token refreshed after 401 in success path. Original request needs to be retried by the caller.');
return Promise.reject(new Error(`Simulated error after 401 token refresh. Status: 401`));
} catch (refreshError) {
console.error('Failed to refresh token during 401 handling:', refreshError);
return Promise.reject(responseOrError);
}
}
return response;
} else {
const error = responseOrError;
if (error?.response?.status === 401 && this.tokenConfig) {
console.log('Received 401 (in error path), attempting to refresh token...');
this.currentToken = undefined;
this.tokenExpiry = undefined;
try {
await this.ensureValidToken();
console.warn('Token refreshed after 401 in error path. Original request needs to be retried by the caller.');
return Promise.reject(error);
} catch (refreshError) {
console.error('Failed to refresh token during 401 handling:', refreshError);
return Promise.reject(error);
}
}
return Promise.reject(error);
}
});
OpenAPI specification (optional)
Sadly can't share at this time
System information (optional)
MacOS: 15.5 (24F74)
Node.js: 23.11.0
PNPM: 9.15.2
NPM: 10.9.2