Skip to content

Commit a3b88dc

Browse files
Copilotmrlubos
authored andcommitted
fix: parse components.headers to resolve crash when schemas reference header components
Agent-Logs-Url: https://github.com/hey-api/openapi-ts/sessions/8e289c88-b983-48a9-84b3-25f60cecebbd
1 parent 9e2f664 commit a3b88dc

14 files changed

Lines changed: 170 additions & 5 deletions

File tree

packages/openapi-ts-tests/main/test/3.0.x.test.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,13 @@ describe(`OpenAPI ${version}`, () => {
151151
}),
152152
description: 'handles snake_case identifier casing',
153153
},
154+
{
155+
config: createConfig({
156+
input: 'components-headers.yaml',
157+
output: 'components-headers',
158+
}),
159+
description: 'handles reusable header components',
160+
},
154161
{
155162
config: createConfig({
156163
input: 'components-request-bodies.json',
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// This file is auto-generated by @hey-api/openapi-ts
2+
3+
export type { ClientOptions, Foo, GetFooData, GetFooResponse, GetFooResponses, XRateLimit } from './types.gen';
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// This file is auto-generated by @hey-api/openapi-ts
2+
3+
export type ClientOptions = {
4+
baseUrl: `${string}://${string}` | (string & {});
5+
};
6+
7+
export type XRateLimit = number;
8+
9+
export type Foo = {
10+
rateLimit?: XRateLimit;
11+
};
12+
13+
export type GetFooData = {
14+
body?: never;
15+
path?: never;
16+
query?: never;
17+
url: '/foo';
18+
};
19+
20+
export type GetFooResponses = {
21+
/**
22+
* OK
23+
*/
24+
200: Foo;
25+
};
26+
27+
export type GetFooResponse = GetFooResponses[keyof GetFooResponses];
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
// This file is auto-generated by @hey-api/openapi-ts
22

3-
export type { _1, ClientOptions, Deep, ExternalAllOfSchema, ExternalAnyOfSchema, ExternalArraySchema, ExternalDeepParam, ExternalDoubleNestedNumeric, ExternalDoubleNestedProp, ExternalIdParam, ExternalMixedBody, ExternalMixedProperties, ExternalModelBody, ExternalNested, ExternalNestedBody, ExternalNestedNumeric, ExternalNestedNumericObjectA, ExternalNestedNumericObjectB, ExternalNestedObjectA, ExternalNestedObjectB, ExternalNumericParam, ExternalSchemaA, ExternalSchemaB, ExternalSchemaC, ExternalSchemaExternalProp, ExternalSchemaExternalPropAlias, ExternalSchemaPathA, ExternalSchemaPathB, ExternalSchemaPropertyA, ExternalSchemaPropertyB, ExternalSchemaPropertyC, ExternalSchemaPropertyD, ExternalSharedModel, ExternalSharedModelWithUuid, ExternalUnionSchema, ExternalUuidBody, ExternalUuidParam, GetExternalArrayData, GetExternalArrayResponse, GetExternalArrayResponses, GetExternalMixedData, GetExternalMixedResponse, GetExternalMixedResponses, GetExternalModelData, GetExternalModelError, GetExternalModelErrors, GetExternalModelResponse, GetExternalModelResponses, GetExternalNestedData, GetExternalNestedResponse, GetExternalNestedResponses, GetExternalPropertiesByIdData, GetExternalPropertiesByIdResponse, GetExternalPropertiesByIdResponses, GetExternalUnionData, GetExternalUnionResponse, GetExternalUnionResponses, GetExternalUuidData, GetExternalUuidResponse, GetExternalUuidResponses, Id, Name, PostExternalArrayData, PostExternalArrayResponse, PostExternalArrayResponses, PostExternalMixedData, PostExternalMixedResponse, PostExternalMixedResponses, PostExternalModelData, PostExternalModelError, PostExternalModelErrors, PostExternalModelResponse, PostExternalModelResponses, PostExternalNestedData, PostExternalNestedResponse, PostExternalNestedResponses, PostExternalUnionData, PostExternalUnionResponse, PostExternalUnionResponses, PutExternalUuidData, PutExternalUuidResponse, PutExternalUuidResponses } from './types.gen';
3+
export type { _1, ClientOptions, Deep, ExternalAllOfSchema, ExternalAnyOfSchema, ExternalArraySchema, ExternalDeepHeader, ExternalDeepParam, ExternalDoubleNestedNumeric, ExternalDoubleNestedProp, ExternalIdHeader, ExternalIdParam, ExternalMixedBody, ExternalMixedProperties, ExternalModelBody, ExternalNested, ExternalNestedBody, ExternalNestedNumeric, ExternalNestedNumericObjectA, ExternalNestedNumericObjectB, ExternalNestedObjectA, ExternalNestedObjectB, ExternalNumericParam, ExternalSchemaA, ExternalSchemaB, ExternalSchemaC, ExternalSchemaExternalProp, ExternalSchemaExternalPropAlias, ExternalSchemaPathA, ExternalSchemaPathB, ExternalSchemaPropertyA, ExternalSchemaPropertyB, ExternalSchemaPropertyC, ExternalSchemaPropertyD, ExternalSharedModel, ExternalSharedModelWithUuid, ExternalUnionSchema, ExternalUuidBody, ExternalUuidHeader, ExternalUuidParam, GetExternalArrayData, GetExternalArrayResponse, GetExternalArrayResponses, GetExternalMixedData, GetExternalMixedResponse, GetExternalMixedResponses, GetExternalModelData, GetExternalModelError, GetExternalModelErrors, GetExternalModelResponse, GetExternalModelResponses, GetExternalNestedData, GetExternalNestedResponse, GetExternalNestedResponses, GetExternalPropertiesByIdData, GetExternalPropertiesByIdResponse, GetExternalPropertiesByIdResponses, GetExternalUnionData, GetExternalUnionResponse, GetExternalUnionResponses, GetExternalUuidData, GetExternalUuidResponse, GetExternalUuidResponses, Id, Name, PostExternalArrayData, PostExternalArrayResponse, PostExternalArrayResponses, PostExternalMixedData, PostExternalMixedResponse, PostExternalMixedResponses, PostExternalModelData, PostExternalModelError, PostExternalModelErrors, PostExternalModelResponse, PostExternalModelResponses, PostExternalNestedData, PostExternalNestedResponse, PostExternalNestedResponses, PostExternalUnionData, PostExternalUnionResponse, PostExternalUnionResponses, PutExternalUuidData, PutExternalUuidResponse, PutExternalUuidResponses } from './types.gen';

packages/openapi-ts-tests/main/test/__snapshots__/3.0.x/external/types.gen.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@ export type ClientOptions = {
44
baseUrl: `${string}://${string}` | (string & {});
55
};
66

7+
export type ExternalIdHeader = Id;
8+
9+
export type ExternalUuidHeader = ExternalSharedModelWithUuid;
10+
11+
export type ExternalDeepHeader = Deep;
12+
713
export type _1 = string;
814

915
export type ExternalSchemaA = ExternalSharedModel;
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
// This file is auto-generated by @hey-api/openapi-ts
22

3-
export type { _1, ClientOptions, Deep, ExternalAllOfSchema, ExternalAnyOfSchema, ExternalArraySchema, ExternalDeepParam, ExternalDoubleNestedNumeric, ExternalDoubleNestedProp, ExternalIdParam, ExternalMixedBody, ExternalMixedProperties, ExternalModelBody, ExternalNested, ExternalNestedBody, ExternalNestedNumeric, ExternalNestedNumericObjectA, ExternalNestedNumericObjectB, ExternalNestedObjectA, ExternalNestedObjectB, ExternalNumericParam, ExternalSchemaA, ExternalSchemaB, ExternalSchemaC, ExternalSchemaExternalProp, ExternalSchemaExternalPropAlias, ExternalSchemaPathA, ExternalSchemaPathB, ExternalSchemaPropertyA, ExternalSchemaPropertyB, ExternalSchemaPropertyC, ExternalSchemaPropertyD, ExternalSharedModel, ExternalSharedModelWithUuid, ExternalUnionSchema, ExternalUuidBody, ExternalUuidParam, GetExternalArrayData, GetExternalArrayResponse, GetExternalArrayResponses, GetExternalMixedData, GetExternalMixedResponse, GetExternalMixedResponses, GetExternalModelData, GetExternalModelError, GetExternalModelErrors, GetExternalModelResponse, GetExternalModelResponses, GetExternalNestedData, GetExternalNestedResponse, GetExternalNestedResponses, GetExternalPropertiesByIdData, GetExternalPropertiesByIdResponse, GetExternalPropertiesByIdResponses, GetExternalUnionData, GetExternalUnionResponse, GetExternalUnionResponses, GetExternalUuidData, GetExternalUuidResponse, GetExternalUuidResponses, Id, Name, PostExternalArrayData, PostExternalArrayResponse, PostExternalArrayResponses, PostExternalMixedData, PostExternalMixedResponse, PostExternalMixedResponses, PostExternalModelData, PostExternalModelError, PostExternalModelErrors, PostExternalModelResponse, PostExternalModelResponses, PostExternalNestedData, PostExternalNestedResponse, PostExternalNestedResponses, PostExternalUnionData, PostExternalUnionResponse, PostExternalUnionResponses, PutExternalUuidData, PutExternalUuidResponse, PutExternalUuidResponses } from './types.gen';
3+
export type { _1, ClientOptions, Deep, ExternalAllOfSchema, ExternalAnyOfSchema, ExternalArraySchema, ExternalDeepHeader, ExternalDeepParam, ExternalDoubleNestedNumeric, ExternalDoubleNestedProp, ExternalIdHeader, ExternalIdParam, ExternalMixedBody, ExternalMixedProperties, ExternalModelBody, ExternalNested, ExternalNestedBody, ExternalNestedNumeric, ExternalNestedNumericObjectA, ExternalNestedNumericObjectB, ExternalNestedObjectA, ExternalNestedObjectB, ExternalNumericParam, ExternalSchemaA, ExternalSchemaB, ExternalSchemaC, ExternalSchemaExternalProp, ExternalSchemaExternalPropAlias, ExternalSchemaPathA, ExternalSchemaPathB, ExternalSchemaPropertyA, ExternalSchemaPropertyB, ExternalSchemaPropertyC, ExternalSchemaPropertyD, ExternalSharedModel, ExternalSharedModelWithUuid, ExternalUnionSchema, ExternalUuidBody, ExternalUuidHeader, ExternalUuidParam, GetExternalArrayData, GetExternalArrayResponse, GetExternalArrayResponses, GetExternalMixedData, GetExternalMixedResponse, GetExternalMixedResponses, GetExternalModelData, GetExternalModelError, GetExternalModelErrors, GetExternalModelResponse, GetExternalModelResponses, GetExternalNestedData, GetExternalNestedResponse, GetExternalNestedResponses, GetExternalPropertiesByIdData, GetExternalPropertiesByIdResponse, GetExternalPropertiesByIdResponses, GetExternalUnionData, GetExternalUnionResponse, GetExternalUnionResponses, GetExternalUuidData, GetExternalUuidResponse, GetExternalUuidResponses, Id, Name, PostExternalArrayData, PostExternalArrayResponse, PostExternalArrayResponses, PostExternalMixedData, PostExternalMixedResponse, PostExternalMixedResponses, PostExternalModelData, PostExternalModelError, PostExternalModelErrors, PostExternalModelResponse, PostExternalModelResponses, PostExternalNestedData, PostExternalNestedResponse, PostExternalNestedResponses, PostExternalUnionData, PostExternalUnionResponse, PostExternalUnionResponses, PutExternalUuidData, PutExternalUuidResponse, PutExternalUuidResponses } from './types.gen';

packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/external/types.gen.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@ export type ClientOptions = {
44
baseUrl: `${string}://${string}` | (string & {});
55
};
66

7+
export type ExternalIdHeader = Id;
8+
9+
export type ExternalUuidHeader = ExternalSharedModelWithUuid;
10+
11+
export type ExternalDeepHeader = Deep;
12+
713
export type _1 = string;
814

915
/**

packages/shared/src/ir/graph.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ export const matchIrPointerToGroup: MatchPointerToGroupFn<IrTopLevelKind> = (poi
2323
operation: /^#\/paths\/[^/]+\/(get|put|post|delete|options|head|patch|trace)$/,
2424
parameter: /^#\/components\/parameters\/[^/]+$/,
2525
requestBody: /^#\/components\/requestBodies\/[^/]+$/,
26-
schema: /^#\/components\/schemas\/[^/]+$/,
26+
schema: /^#\/components\/(headers|schemas)\/[^/]+$/,
2727
server: /^#\/servers\/(\d+|[^/]+)$/,
2828
webhook: /^#\/webhooks\/[^/]+\/(get|put|post|delete|options|head|patch|trace)$/,
2929
};

packages/shared/src/ir/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ interface IRBodyObject {
1717
}
1818

1919
interface IRComponentsObject {
20+
headers?: Record<string, IRSchemaObject>;
2021
parameters?: Record<string, IRParameterObject>;
2122
requestBodies?: Record<string, IRRequestBodyObject>;
2223
schemas?: Record<string, IRSchemaObject>;

packages/shared/src/openApi/3.0.x/parser/index.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import { filterSpec } from './filter';
1616
import { parsePathOperation } from './operation';
1717
import { parametersArrayToObject, parseParameter } from './parameter';
1818
import { parseRequestBody } from './requestBody';
19-
import { parseSchema } from './schema';
19+
import { parseHeader, parseSchema } from './schema';
2020
import { parseServers } from './server';
2121
import { validateOpenApiSpec } from './validate';
2222

@@ -62,6 +62,23 @@ export const parseV3_0_X = (context: Context<OpenAPIV3.Document>) => {
6262
securitySchemesMap.set(name, securitySchemeObject);
6363
}
6464

65+
for (const name in context.spec.components.headers) {
66+
const $ref = `#/components/headers/${name}`;
67+
const headerOrReference = context.spec.components.headers[name]!;
68+
const header =
69+
'$ref' in headerOrReference
70+
? context.resolveRef<OpenAPIV3.HeaderObject>(headerOrReference.$ref)
71+
: headerOrReference;
72+
73+
if (header.schema) {
74+
parseHeader({
75+
$ref,
76+
context,
77+
schema: header.schema,
78+
});
79+
}
80+
}
81+
6582
for (const name in context.spec.components.parameters) {
6683
const $ref = `#/components/parameters/${name}`;
6784
const parameterOrReference = context.spec.components.parameters[name]!;

0 commit comments

Comments
 (0)