Skip to content

Commit 1a3f668

Browse files
authored
Merge pull request #1892 from hey-api/fix/fetch-spec-options
fix: allow passing fetch options to the request resolving a specification
2 parents 474639e + 29fa764 commit 1a3f668

File tree

8 files changed

+99
-46
lines changed

8 files changed

+99
-46
lines changed

.changeset/curvy-seas-camp.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@hey-api/openapi-ts': patch
3+
---
4+
5+
fix: allow passing fetch options to the request resolving a specification

packages/openapi-ts-tests/test/openapi-ts.config.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@ export default defineConfig(() => {
1717
input: {
1818
branch: 'main',
1919
// exclude: '^#/components/schemas/ModelWithCircularReference$',
20+
// fetch: {
21+
// headers: {
22+
// 'x-foo': 'bar',
23+
// },
24+
// },
2025
// include:
2126
// '^(#/components/schemas/import|#/paths/api/v{api-version}/simple/options)$',
2227
organization: 'hey-api',

packages/openapi-ts/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@
7878
"node": "^18.18.0 || ^20.9.0 || >=22.10.0"
7979
},
8080
"dependencies": {
81-
"@hey-api/json-schema-ref-parser": "1.0.3",
81+
"@hey-api/json-schema-ref-parser": "1.0.4",
8282
"c12": "2.0.1",
8383
"commander": "13.0.0",
8484
"handlebars": "4.7.8"

packages/openapi-ts/src/createClient.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,7 @@ export const createClient = async ({
193193

194194
Performance.start('spec');
195195
const { data, error, response } = await getSpec({
196+
fetchOptions: config.input.fetch,
196197
inputPath: inputPath.path,
197198
timeout,
198199
watch,

packages/openapi-ts/src/getSpec.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
sendRequest,
66
} from '@hey-api/json-schema-ref-parser';
77

8+
import { mergeHeaders } from './mergeHeaders';
89
import type { Config } from './types/config';
910
import type { WatchValues } from './types/types';
1011

@@ -21,10 +22,12 @@ interface SpecError {
2122
}
2223

2324
export const getSpec = async ({
25+
fetchOptions,
2426
inputPath,
2527
timeout,
2628
watch,
2729
}: {
30+
fetchOptions?: RequestInit;
2831
inputPath: Config['input']['path'];
2932
timeout: number;
3033
watch: WatchValues;
@@ -42,9 +45,10 @@ export const getSpec = async ({
4245
if (watch.lastValue && watch.isHeadMethodSupported !== false) {
4346
try {
4447
const request = await sendRequest({
45-
init: {
46-
headers: watch.headers,
48+
fetchOptions: {
4749
method: 'HEAD',
50+
...fetchOptions,
51+
headers: mergeHeaders(fetchOptions?.headers, watch.headers),
4852
},
4953
timeout,
5054
url: resolvedInput.path,
@@ -118,8 +122,9 @@ export const getSpec = async ({
118122

119123
try {
120124
const request = await sendRequest({
121-
init: {
125+
fetchOptions: {
122126
method: 'GET',
127+
...fetchOptions,
123128
},
124129
timeout,
125130
url: resolvedInput.path,
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// copy-pasted from @hey-api/client-fetch
2+
export const mergeHeaders = (
3+
...headers: Array<RequestInit['headers'] | undefined>
4+
): Headers => {
5+
const mergedHeaders = new Headers();
6+
for (const header of headers) {
7+
if (!header || typeof header !== 'object') {
8+
continue;
9+
}
10+
11+
const iterator =
12+
header instanceof Headers ? header.entries() : Object.entries(header);
13+
14+
for (const [key, value] of iterator) {
15+
if (value === null) {
16+
mergedHeaders.delete(key);
17+
} else if (Array.isArray(value)) {
18+
for (const v of value) {
19+
mergedHeaders.append(key, v as string);
20+
}
21+
} else if (value !== undefined) {
22+
// assume object headers are meant to be JSON stringified, i.e. their
23+
// content value in OpenAPI specification is 'application/json'
24+
mergedHeaders.set(
25+
key,
26+
typeof value === 'object' ? JSON.stringify(value) : (value as string),
27+
);
28+
}
29+
}
30+
}
31+
return mergedHeaders;
32+
};

packages/openapi-ts/src/types/config.d.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,11 @@ interface Input {
4949
* schema: '^#/components/schemas/Foo$'
5050
*/
5151
exclude?: string;
52+
/**
53+
* You pass any valid Fetch API options to the request for fetching your
54+
* specification. This is useful if your file is behind auth for example.
55+
*/
56+
fetch?: RequestInit;
5257
/**
5358
* Process only parts matching the regular expression. You can select both
5459
* operations and components by reference within the bundled input. In
@@ -133,7 +138,7 @@ export interface UserConfig {
133138
input:
134139
| 'https://get.heyapi.dev/<organization>/<project>'
135140
| (string & {})
136-
| Record<string, unknown>
141+
| (Record<string, unknown> & { path?: never })
137142
| Input;
138143
/**
139144
* The relative location of the logs folder

0 commit comments

Comments
 (0)