diff --git a/.changeset/slow-vans-win.md b/.changeset/slow-vans-win.md new file mode 100644 index 000000000..5f2a5f923 --- /dev/null +++ b/.changeset/slow-vans-win.md @@ -0,0 +1,5 @@ +--- +"swagger-typescript-api": patch +--- + +Ensure discriminators are just after enums in components list to avoid cyclic errors diff --git a/src/code-gen-process.ts b/src/code-gen-process.ts index 320273f8e..8793b0e8c 100644 --- a/src/code-gen-process.ts +++ b/src/code-gen-process.ts @@ -127,6 +127,9 @@ export class CodeGenProcess { }), ); + // Set all discriminators at the top + this.schemaComponentsMap.discriminatorsFirst(); + // Put all enums at the top (before discriminators) this.schemaComponentsMap.enumsFirst(); const componentsToParse: SchemaComponent[] = diff --git a/src/schema-components-map.ts b/src/schema-components-map.ts index 8eee01181..e27573edf 100644 --- a/src/schema-components-map.ts +++ b/src/schema-components-map.ts @@ -77,4 +77,13 @@ export class SchemaComponentsMap { return 0; }); } + + // Ensure discriminators are at the top of components list + discriminatorsFirst() { + this._data.sort((a, b) => { + if (Object.keys(a.rawTypeData || {}).includes("discriminator")) return -1; + if (Object.keys(b.rawTypeData || {}).includes("discriminator")) return 1; + return 0; + }); + } } diff --git a/tests/spec/discriminator/__snapshots__/basic.test.ts.snap b/tests/spec/discriminator/__snapshots__/basic.test.ts.snap index 252d94362..ceeccad59 100644 --- a/tests/spec/discriminator/__snapshots__/basic.test.ts.snap +++ b/tests/spec/discriminator/__snapshots__/basic.test.ts.snap @@ -25,6 +25,74 @@ export enum BlockDTOEnum { Kek = "kek", } +/** kek pek */ +export type Variant = + | ({ + type: "update"; + } & VariantUpdate) + | ({ + type: "undo"; + } & VariantUndo) + | ({ + type: "rollback"; + } & VariantRollback) + | ({ + type: "scale"; + } & VariantScale) + | ({ + type: "resources"; + } & VariantResources) + | ({ + type: "firewall"; + } & VariantFirewall) + | ({ + type: "gateway"; + } & VariantGateway); + +export type InvalidDiscriminatorPropertyName = + BaseInvalidDiscriminatorPropertyName & + ( + | BaseInvalidDiscriminatorPropertyNameTypeMapping<"num", number> + | BaseInvalidDiscriminatorPropertyNameTypeMapping<"str", string> + ); + +export type PetWithEnum = BasePetWithEnum & + ( + | BasePetWithEnumPetTypeMapping + | BasePetWithEnumPetTypeMapping + | BasePetWithEnumPetTypeMapping + ); + +export type PetOnlyDiscriminator = + | ({ + pet_type: "dog"; + } & Dog) + | ({ + pet_type: "cat"; + } & Cat) + | ({ + pet_type: "lizard"; + } & Lizard); + +export type Pet = BasePet & + ( + | BasePetPetTypeMapping<"dog", Dog> + | BasePetPetTypeMapping<"cat", Cat> + | BasePetPetTypeMapping<"lizard", Lizard> + ); + +export type BlockDTO = BaseBlockDto & + ( + | BaseBlockDtoTypeMapping<"csv", CsvBlockDTO> + | BaseBlockDtoTypeMapping<"file", FileBlockDTO> + ); + +export type BlockDTOWithEnum = BaseBlockDtoWithEnum & + ( + | BaseBlockDtoWithEnumTypeMapping + | BaseBlockDtoWithEnumTypeMapping + ); + export type SimpleDiscriminator = SimpleObject | ComplexObject; export interface SimpleObject { @@ -35,12 +103,6 @@ export interface ComplexObject { objectType: string; } -export type BlockDTOWithEnum = BaseBlockDtoWithEnum & - ( - | BaseBlockDtoWithEnumTypeMapping - | BaseBlockDtoWithEnumTypeMapping - ); - export type CsvBlockWithEnumDTO = BaseBlockDtoWithEnum & { type: BlockDTOEnum.Csv; text: string; @@ -51,12 +113,6 @@ export type FileBlockWithEnumDTO = BaseBlockDtoWithEnum & { fileId: string; }; -export type BlockDTO = BaseBlockDto & - ( - | BaseBlockDtoTypeMapping<"csv", CsvBlockDTO> - | BaseBlockDtoTypeMapping<"file", FileBlockDTO> - ); - export type CsvBlockDTO = BaseBlockDto & { /** @default "csv" */ type: "csv"; @@ -69,24 +125,6 @@ export type FileBlockDTO = BaseBlockDto & { fileId: string; }; -export type Pet = BasePet & - ( - | BasePetPetTypeMapping<"dog", Dog> - | BasePetPetTypeMapping<"cat", Cat> - | BasePetPetTypeMapping<"lizard", Lizard> - ); - -export type PetOnlyDiscriminator = - | ({ - pet_type: "dog"; - } & Dog) - | ({ - pet_type: "cat"; - } & Cat) - | ({ - pet_type: "lizard"; - } & Lizard); - export type Cat = BasePet & { name?: string; }; @@ -99,13 +137,6 @@ export type Lizard = BasePet & { lovesRocks?: boolean; }; -export type PetWithEnum = BasePetWithEnum & - ( - | BasePetWithEnumPetTypeMapping - | BasePetWithEnumPetTypeMapping - | BasePetWithEnumPetTypeMapping - ); - export type CatWithEnum = BasePetWithEnum & { name?: string; }; @@ -118,37 +149,6 @@ export type LizardWithEnum = BasePetWithEnum & { lovesRocks?: boolean; }; -export type InvalidDiscriminatorPropertyName = - BaseInvalidDiscriminatorPropertyName & - ( - | BaseInvalidDiscriminatorPropertyNameTypeMapping<"num", number> - | BaseInvalidDiscriminatorPropertyNameTypeMapping<"str", string> - ); - -/** kek pek */ -export type Variant = - | ({ - type: "update"; - } & VariantUpdate) - | ({ - type: "undo"; - } & VariantUndo) - | ({ - type: "rollback"; - } & VariantRollback) - | ({ - type: "scale"; - } & VariantScale) - | ({ - type: "resources"; - } & VariantResources) - | ({ - type: "firewall"; - } & VariantFirewall) - | ({ - type: "gateway"; - } & VariantGateway); - /** Proposal to change firewall rules for deployment. */ export interface VariantFirewall { /** asdasdasdasdasdsad added to deployment. If not set, no rules are added. */ @@ -196,21 +196,18 @@ export interface VariantRollback { /** asdasdasdasdasdn */ export type VariantUndo = object; -interface BaseBlockDtoWithEnum { - title: string; - type: BlockDTOEnum; -} +type BaseInvalidDiscriminatorPropertyName = object; -type BaseBlockDtoWithEnumTypeMapping = { - type: Key; +type BaseInvalidDiscriminatorPropertyNameTypeMapping = { + "@type": Key; } & Type; -interface BaseBlockDto { - title: string; +interface BasePetWithEnum { + pet_type: PetEnum; } -type BaseBlockDtoTypeMapping = { - type: Key; +type BasePetWithEnumPetTypeMapping = { + pet_type: Key; } & Type; interface BasePet { @@ -221,18 +218,21 @@ type BasePetPetTypeMapping = { pet_type: Key; } & Type; -interface BasePetWithEnum { - pet_type: PetEnum; +interface BaseBlockDto { + title: string; } -type BasePetWithEnumPetTypeMapping = { - pet_type: Key; +type BaseBlockDtoTypeMapping = { + type: Key; } & Type; -type BaseInvalidDiscriminatorPropertyName = object; +interface BaseBlockDtoWithEnum { + title: string; + type: BlockDTOEnum; +} -type BaseInvalidDiscriminatorPropertyNameTypeMapping = { - "@type": Key; +type BaseBlockDtoWithEnumTypeMapping = { + type: Key; } & Type; " `; diff --git a/tests/spec/enumNotFirstInComponents/__snapshots__/basic.test.ts.snap b/tests/spec/enumNotFirstInComponents/__snapshots__/basic.test.ts.snap index 63de68be9..87475715b 100644 --- a/tests/spec/enumNotFirstInComponents/__snapshots__/basic.test.ts.snap +++ b/tests/spec/enumNotFirstInComponents/__snapshots__/basic.test.ts.snap @@ -18,6 +18,12 @@ export enum ExampleEnum { Example2 = "Example2", } +export type ExampleObject = BaseExampleObject & + ( + | BaseExampleObjectTypeMapping + | BaseExampleObjectTypeMapping + ); + export interface DtoExample1 { name: string; age: number; @@ -29,12 +35,6 @@ export interface DtoExample2 { description: string; } -export type ExampleObject = BaseExampleObject & - ( - | BaseExampleObjectTypeMapping - | BaseExampleObjectTypeMapping - ); - interface BaseExampleObject { type?: ExampleEnum; }