Skip to content

Commit 243d33a

Browse files
Copilotmrlubos
andcommitted
Fix output header config not applied to bundled client files
Co-authored-by: mrlubos <12529395+mrlubos@users.noreply.github.com>
1 parent 3e974bb commit 243d33a

3 files changed

Lines changed: 72 additions & 3 deletions

File tree

packages/openapi-ts/src/generate/__tests__/client.test.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,51 @@
11
import path from 'node:path';
22

3+
/**
4+
* Replicates the outputHeaderToPrefix logic from generate/client.ts for testing.
5+
*/
6+
function outputHeaderToPrefix(header: unknown): string {
7+
if (header == null || typeof header === 'function') return '';
8+
const lines = Array.isArray(header)
9+
? (header as string[]).flatMap((line) => line.split(/\r?\n/))
10+
: (header as string).split(/\r?\n/);
11+
const content = lines.join('\n');
12+
return content ? `${content}\n\n` : '';
13+
}
14+
15+
describe('outputHeaderToPrefix logic', () => {
16+
it('returns default comment for string header', () => {
17+
const result = outputHeaderToPrefix('// This file is auto-generated by @hey-api/openapi-ts');
18+
expect(result).toBe('// This file is auto-generated by @hey-api/openapi-ts\n\n');
19+
});
20+
21+
it('returns joined lines for array header', () => {
22+
const result = outputHeaderToPrefix([
23+
'// This file is auto-generated by @hey-api/openapi-ts',
24+
'// @ts-nocheck',
25+
]);
26+
expect(result).toBe(
27+
'// This file is auto-generated by @hey-api/openapi-ts\n// @ts-nocheck\n\n',
28+
);
29+
});
30+
31+
it('returns empty string for null header', () => {
32+
expect(outputHeaderToPrefix(null)).toBe('');
33+
});
34+
35+
it('returns empty string for undefined header', () => {
36+
expect(outputHeaderToPrefix(undefined)).toBe('');
37+
});
38+
39+
it('returns empty string for function header', () => {
40+
expect(outputHeaderToPrefix(() => '// dynamic')).toBe('');
41+
});
42+
43+
it('handles string with embedded newlines', () => {
44+
const result = outputHeaderToPrefix('// line1\n// line2');
45+
expect(result).toBe('// line1\n// line2\n\n');
46+
});
47+
});
48+
349
describe('isDevMode logic', () => {
450
const scenarios: ReadonlyArray<{
551
description: string;

packages/openapi-ts/src/generate/client.ts

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import path from 'node:path';
33
import { fileURLToPath } from 'node:url';
44

55
import type { IProject, ProjectRenderMeta } from '@hey-api/codegen-core';
6-
import type { DefinePlugin } from '@hey-api/shared';
6+
import type { DefinePlugin, OutputHeader } from '@hey-api/shared';
77
import { ensureDirSync } from '@hey-api/shared';
88

99
import type { Config } from '../config/types';
@@ -53,6 +53,20 @@ function getClientBundlePaths(pluginName: string): {
5353
};
5454
}
5555

56+
/**
57+
* Converts an {@link OutputHeader} value to a string prefix for file content.
58+
* Returns an empty string when the header is null, undefined, or a function
59+
* (functions require a render context which is not available for bundled files).
60+
*/
61+
function outputHeaderToPrefix(header: OutputHeader): string {
62+
if (header == null || typeof header === 'function') return '';
63+
const lines = Array.isArray(header)
64+
? header.flatMap((line) => line.split(/\r?\n/))
65+
: header.split(/\r?\n/);
66+
const content = lines.join('\n');
67+
return content ? `${content}\n\n` : '';
68+
}
69+
5670
/**
5771
* Returns absolute path to the client folder. This is hard-coded for now.
5872
*/
@@ -114,11 +128,13 @@ function renameFile({
114128

115129
function replaceImports({
116130
filePath,
131+
header,
117132
isDevMode,
118133
meta,
119134
renamed,
120135
}: {
121136
filePath: string;
137+
header?: string;
122138
isDevMode?: boolean;
123139
meta: ProjectRenderMeta;
124140
renamed: Map<string, string>;
@@ -148,9 +164,10 @@ function replaceImports({
148164
return replacedMatch;
149165
});
150166

151-
const header = '// This file is auto-generated by @hey-api/openapi-ts\n\n';
167+
const fileHeader =
168+
header !== undefined ? header : '// This file is auto-generated by @hey-api/openapi-ts\n\n';
152169

153-
content = `${header}${content}`;
170+
content = `${fileHeader}${content}`;
154171

155172
fs.writeFileSync(filePath, content, 'utf8');
156173
}
@@ -159,18 +176,21 @@ function replaceImports({
159176
* Creates a `client` folder containing the same modules as the client package.
160177
*/
161178
export function generateClientBundle({
179+
header,
162180
meta,
163181
outputPath,
164182
plugin,
165183
project,
166184
}: {
185+
header?: OutputHeader;
167186
meta: ProjectRenderMeta;
168187
outputPath: string;
169188
plugin: DefinePlugin<Client.Config & { name: string }>['Config'];
170189
project?: IProject;
171190
}): Map<string, string> | undefined {
172191
const renamed = new Map<string, string>();
173192
const devMode = isDevMode();
193+
const headerPrefix = outputHeaderToPrefix(header);
174194

175195
// copy Hey API clients to output
176196
const isHeyApiClientPlugin = plugin.name.startsWith('@hey-api/client-');
@@ -211,6 +231,7 @@ export function generateClientBundle({
211231
for (const file of coreFiles) {
212232
replaceImports({
213233
filePath: path.resolve(coreOutputPath, file),
234+
header: headerPrefix,
214235
isDevMode: devMode,
215236
meta,
216237
renamed,
@@ -221,6 +242,7 @@ export function generateClientBundle({
221242
for (const file of clientFiles) {
222243
replaceImports({
223244
filePath: path.resolve(clientOutputPath, file),
245+
header: headerPrefix,
224246
isDevMode: devMode,
225247
meta,
226248
renamed,

packages/openapi-ts/src/generate/output.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ export async function generateOutput(context: Context): Promise<void> {
2424
// not proud of this one
2525
// @ts-expect-error
2626
config._FRAGILE_CLIENT_BUNDLE_RENAMED = generateClientBundle({
27+
header: config.output.header,
2728
meta: {
2829
importFileExtension: config.output.importFileExtension,
2930
},

0 commit comments

Comments
 (0)