Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/dynamicref-support.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@hey-api/shared": minor
"@hey-api/spec-types": minor
---

add `$dynamicRef` / `$dynamicAnchor` schema resolution for OpenAPI 3.1
21 changes: 21 additions & 0 deletions packages/openapi-ts-tests/main/test/3.1.x.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1015,6 +1015,27 @@ describe(`OpenAPI ${version}`, () => {
}),
description: 'anyOf string and binary string',
},
{
config: createConfig({
input: 'dynamicref-petstore-showcase.yaml',
output: 'dynamicref-petstore-showcase',
}),
description: 'resolves $dynamicRef in petstore showcase',
},
{
config: createConfig({
input: 'dynamicref-external-ref.yaml',
output: 'dynamicref-external-ref',
}),
description: 'handles external $dynamicRef without crashing',
},
{
config: createConfig({
input: 'dynamicref-scope-isolation.yaml',
output: 'dynamicref-scope-isolation',
}),
description: 'keeps $dynamicRef bindings isolated between sibling schemas',
},
];

it.each(scenarios)('$description', async ({ config }) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// This file is auto-generated by @hey-api/openapi-ts

export type { ClientOptions, Container, GetContainersData, GetContainersErrors, GetContainersResponse, GetContainersResponses } from './types.gen';
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// This file is auto-generated by @hey-api/openapi-ts

export type ClientOptions = {
baseUrl: 'https://api.dynamicref.test' | (string & {});
};

export type Container = {
id: string;
item: unknown;
};

export type GetContainersData = {
body?: never;
path?: never;
query?: never;
url: '/containers';
};

export type GetContainersErrors = {
/**
* Error response
*/
default: unknown;
};

export type GetContainersResponses = {
/**
* Container list
*/
200: Array<Container>;
};

export type GetContainersResponse = GetContainersResponses[keyof GetContainersResponses];
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// This file is auto-generated by @hey-api/openapi-ts

export type { ApiEnvelopeTemplate, BaseSpeciesCategory, ClientOptions, CreatePetData, CreatePetErrors, CreatePetResponse, CreatePetResponses, Document, GetPetData, GetPetErrors, GetPetResponse, GetPetResponses, GetShelterResourcesData, GetShelterResourcesErrors, GetShelterResourcesResponse, GetShelterResourcesResponses, GetSpeciesTreeData, GetSpeciesTreeErrors, GetSpeciesTreeResponse, GetSpeciesTreeResponses, Link, ListOwnersData, ListOwnersErrors, ListOwnersResponse, ListOwnersResponses, ListPetsData, ListPetsErrors, ListPetsResponse, ListPetsResponses, LocalizedSpeciesCategory, Owner, PaginatedOwnerItems, PaginatedPetItems, PaginatedTemplate, Pet, PetCreateRequest, PetFields, ShelterFolder, ShelterFolderTemplate, ShelterResource } from './types.gen';
Original file line number Diff line number Diff line change
@@ -0,0 +1,236 @@
// This file is auto-generated by @hey-api/openapi-ts

export type ClientOptions = {
baseUrl: 'https://api.petstore.example' | (string & {});
};

export type Link = {
href?: string;
};

export type PetFields = {
name: string;
species: string;
status: 'available' | 'pending' | 'adopted';
tag?: Array<string>;
};

export type PetCreateRequest = PetFields;

export type Pet = {
id: string;
} & PetFields;

export type Owner = {
id: string;
name: string;
email: string;
};

export type ApiEnvelopeTemplate<DataType> = {
data: DataType;
requestId: string;
links?: {
[key: string]: Link;
};
};

export type PaginatedTemplate<ItemType> = {
items: Array<ItemType>;
total: number;
page: number;
pageSize: number;
};

export type PaginatedPetItems = PaginatedTemplate<Pet>;

export type PaginatedOwnerItems = PaginatedTemplate<Owner>;

export type BaseSpeciesCategory = {
id: string;
label: string;
children: Array<BaseSpeciesCategory>;
};

export type LocalizedSpeciesCategory = {
id: string;
label: string;
children: Array<LocalizedSpeciesCategory>;
} & {
locale: string;
displayName: string;
};

export type Document = {
kind: 'document';
id: string;
title: string;
};

export type ShelterFolderTemplate<FolderType, ResourceType> = {
kind: 'folder';
id: string;
name: string;
children: Array<Document | FolderType>;
shortcuts?: Array<ResourceType>;
};

export type ShelterFolder = {
kind: 'folder';
id: string;
name: string;
children: Array<Document | ShelterFolder>;
shortcuts?: Array<ShelterResource>;
} & {
accessLevel: 'public' | 'staff' | 'admin';
};

export type ShelterResource = Document | ShelterFolder;

export type ListPetsData = {
body?: never;
path?: never;
query?: {
page?: number;
pageSize?: number;
};
url: '/pets';
};

export type ListPetsErrors = {
/**
* Bad request
*/
400: unknown;
};

export type ListPetsResponses = {
/**
* Paginated list of pets
*/
200: ApiEnvelopeTemplate<PaginatedPetItems>;
};

export type ListPetsResponse = ListPetsResponses[keyof ListPetsResponses];

export type CreatePetData = {
body: PetFields;
path?: never;
query?: never;
url: '/pets';
};

export type CreatePetErrors = {
/**
* Bad request
*/
400: unknown;
};

export type CreatePetResponses = {
/**
* Created pet
*/
201: ApiEnvelopeTemplate<Pet>;
};

export type CreatePetResponse = CreatePetResponses[keyof CreatePetResponses];

export type GetPetData = {
body?: never;
path: {
petId: string;
};
query?: never;
url: '/pets/{petId}';
};

export type GetPetErrors = {
/**
* Not found
*/
404: unknown;
};

export type GetPetResponses = {
/**
* A single pet
*/
200: ApiEnvelopeTemplate<Pet>;
};

export type GetPetResponse = GetPetResponses[keyof GetPetResponses];

export type ListOwnersData = {
body?: never;
path?: never;
query?: {
page?: number;
pageSize?: number;
};
url: '/owners';
};

export type ListOwnersErrors = {
/**
* Bad request
*/
400: unknown;
};

export type ListOwnersResponses = {
/**
* Paginated list of owners
*/
200: ApiEnvelopeTemplate<PaginatedOwnerItems>;
};

export type ListOwnersResponse = ListOwnersResponses[keyof ListOwnersResponses];

export type GetSpeciesTreeData = {
body?: never;
path?: never;
query?: never;
url: '/species/tree';
};

export type GetSpeciesTreeErrors = {
/**
* Bad request
*/
400: unknown;
};

export type GetSpeciesTreeResponses = {
/**
* Localized recursive species category tree
*/
200: LocalizedSpeciesCategory;
};

export type GetSpeciesTreeResponse = GetSpeciesTreeResponses[keyof GetSpeciesTreeResponses];

export type GetShelterResourcesData = {
body?: never;
path: {
shelterId: string;
};
query?: never;
url: '/shelters/{shelterId}/resources';
};

export type GetShelterResourcesErrors = {
/**
* Not found
*/
404: unknown;
};

export type GetShelterResourcesResponses = {
/**
* Shelter resource tree
*/
200: ShelterResource;
};

export type GetShelterResourcesResponse = GetShelterResourcesResponses[keyof GetShelterResourcesResponses];
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// This file is auto-generated by @hey-api/openapi-ts

export type { ClientOptions, GetScopeData, GetScopeErrors, GetScopeResponse, GetScopeResponses, ScopeIsolationResponse, User } from './types.gen';
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// This file is auto-generated by @hey-api/openapi-ts

export type ClientOptions = {
baseUrl: 'https://api.dynamicref.test' | (string & {});
};

export type User = {
id: string;
email: string;
};

export type ScopeIsolationResponse = {
boundItems: Array<User>;
unboundItem: unknown;
};

export type GetScopeData = {
body?: never;
path?: never;
query?: never;
url: '/scope';
};

export type GetScopeErrors = {
/**
* Error response
*/
default: unknown;
};

export type GetScopeResponses = {
/**
* Scope isolation example
*/
200: ScopeIsolationResponse;
};

export type GetScopeResponse = GetScopeResponses[keyof GetScopeResponses];
Original file line number Diff line number Diff line change
Expand Up @@ -59,5 +59,12 @@ export function exportAst({
.export()
.$if(plugin.config.comments && createSchemaComment(schema), (t, v) => t.doc(v))
.type(final.type);

if (schema.typeParams?.length) {
for (const param of schema.typeParams) {
node.generic(param.paramName);
}
}

plugin.node(node);
}
Loading
Loading