[nextjs]can you create a interceptor param in createClientConfig?
Description
because i need create a interceptor before use clinet,so I need to add the configuration when creating the client ,like this
export const createClientConfig: CreateClientConfig = (config) => ({
...config,
baseUrl: 'https://example.com',
requestInterceptor:()=>{},
responserequestInterceptor:()=>{}
});
The generated code
export type CreateClientConfig<T extends DefaultClientOptions = ClientOptions> = (
override?: Config<DefaultClientOptions & T>,
) => Config<Required<DefaultClientOptions> & T>
export const client = createClient(
createClientConfig(
createConfig<ClientOptions>({
baseUrl: "https://127.0.0.1:3000",
}),
),
)
client.interceptors.request.use(()=>{})
I'm not sure if this is a good issue. Is there a better way to get it?
@recvexi what did you end up doing?
@recvexi what did you end up doing?
I wrote a script to do this temporarily
# openapi.sh
# 运行 openapi-ts
pnpm run openapi-ts
# 在 client.gen.ts 末尾追加内容
echo '
import { requestInterceptor } from "../interceptors"
client.interceptors.request.use(requestInterceptor)
' >> ../service/gen/client.gen.ts
this is much needed
这是非常需要的
我应该重新打开 issue 吗?
这是非常需要的
我应该重新打开 issue 吗?
I am using nextjs and i haven't found the right place for the middlewares. based on your response, i ended up writing a custom script that injects middleware into client.ge.ts, but i can see it is not the safest option
// This file is auto-generated by @hey-api/openapi-ts
import { createClientConfig, setFetchClientMiddleware } from '@/utils/fetch-client'; // <-- MY CHANGE
import { type ClientOptions, type Config, createClient, createConfig } from './client';
import type { ClientOptions as ClientOptions2 } from './types.gen';
/**
* The `createClientConfig()` function will be called on client initialization
* and the returned object will become the client's initial configuration.
*
* You may want to initialize your client this way instead of calling
* `setConfig()`. This is useful for example if you're using Next.js
* to ensure your client always has the correct values.
*/
export type CreateClientConfig<T extends ClientOptions = ClientOptions2> = (override?: Config<ClientOptions & T>) => Config<Required<ClientOptions> & T>;
const client = createClient(createClientConfig(createConfig<ClientOptions2>())); // <-- MY CHANGE
setFetchClientMiddleware(client); // <-- MY CHANGE
export { client }; // <-- MY CHANGE
same issue, much needed
much needed
Claude wrote this script, adding an entrypoint addInterceptors(client) to customise the client before returning it.
The added import is coming from @/api/common/interceptors in my case, you'd need to adapt this path to your needs.
I also export the createClientConfig from @/api/common/client which you would need to adapt.
#!/usr/bin/env node
/**
* Patch Generated API Client
*
* This script performs 4 transformations on the auto-generated client.gen.ts:
* 1. Add import for addInterceptors
* 2. Remove export from client const declaration (if present)
* 3. Add addInterceptors(client) call after client creation
* 4. Ensure client is exported separately at the end
*/
const fs = require('fs');
const path = require('path');
const CLIENT_FILE = path.join(
__dirname,
'../src/api/generated/client.gen.ts' // <---- ADAPT THIS TO YOUR NEEDS
);
function patchGeneratedClient() {
console.log('🔧 Patching generated client...');
if (!fs.existsSync(CLIENT_FILE)) {
console.error('❌ Generated client file not found:', CLIENT_FILE);
process.exit(1);
}
let content = fs.readFileSync(CLIENT_FILE, 'utf8');
// Check if already patched
if (content.includes('addInterceptors(client)')) {
console.log('✅ Client already patched');
return;
}
// Step 1: Add addInterceptors import after createClientConfig import
if (!content.includes("from '@/api/common/interceptors'")) {
const createClientConfigImport = "import { createClientConfig } from '@/api/common/client';";
const importIndex = content.indexOf(createClientConfigImport);
if (importIndex === -1) {
console.error('❌ Could not find createClientConfig import');
process.exit(1);
}
const afterImport = importIndex + createClientConfigImport.length;
const interceptorImport = "\nimport { addInterceptors } from '@/api/common/interceptors';";
content = content.slice(0, afterImport) + interceptorImport + content.slice(afterImport);
}
// Step 2: Remove export from client const declaration (if present)
content = content.replace(/export const client = /, 'const client = ');
// Step 3: Add addInterceptors(client) call after client creation
const clientPattern = /(const client = createClient\([\s\S]*?\);)/;
const match = content.match(clientPattern);
if (!match) {
console.error('❌ Could not find client creation statement');
process.exit(1);
}
const replacement = `${match[1]}\n\naddInterceptors(client);`;
content = content.replace(clientPattern, replacement);
// Step 4: Ensure client is exported separately (if not already present)
if (!content.includes('export { client }')) {
content = content.trimEnd() + '\n\nexport { client };\n';
}
// Write patched file
fs.writeFileSync(CLIENT_FILE, content, 'utf8');
console.log('✅ Generated client patched successfully');
}
try {
patchGeneratedClient();
process.exit(0);
} catch (error) {
console.error('❌ Failed to patch generated client:', error.message);
process.exit(1);
}