Skip to content
Merged
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
5 changes: 5 additions & 0 deletions .changeset/slow-vans-win.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"swagger-typescript-api": patch
---

Ensure discriminators are just after enums in components list to avoid cyclic errors
3 changes: 3 additions & 0 deletions src/code-gen-process.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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[] =
Expand Down
9 changes: 9 additions & 0 deletions src/schema-components-map.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
});
}
}
170 changes: 85 additions & 85 deletions tests/spec/discriminator/__snapshots__/basic.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -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<PetEnum.Dog, DogWithEnum>
| BasePetWithEnumPetTypeMapping<PetEnum.Cat, CatWithEnum>
| BasePetWithEnumPetTypeMapping<PetEnum.Lizard, LizardWithEnum>
);

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<BlockDTOEnum.Csv, CsvBlockWithEnumDTO>
| BaseBlockDtoWithEnumTypeMapping<BlockDTOEnum.File, FileBlockWithEnumDTO>
);

export type SimpleDiscriminator = SimpleObject | ComplexObject;

export interface SimpleObject {
Expand All @@ -35,12 +103,6 @@ export interface ComplexObject {
objectType: string;
}

export type BlockDTOWithEnum = BaseBlockDtoWithEnum &
(
| BaseBlockDtoWithEnumTypeMapping<BlockDTOEnum.Csv, CsvBlockWithEnumDTO>
| BaseBlockDtoWithEnumTypeMapping<BlockDTOEnum.File, FileBlockWithEnumDTO>
);

export type CsvBlockWithEnumDTO = BaseBlockDtoWithEnum & {
type: BlockDTOEnum.Csv;
text: string;
Expand All @@ -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";
Expand All @@ -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;
};
Expand All @@ -99,13 +137,6 @@ export type Lizard = BasePet & {
lovesRocks?: boolean;
};

export type PetWithEnum = BasePetWithEnum &
(
| BasePetWithEnumPetTypeMapping<PetEnum.Dog, DogWithEnum>
| BasePetWithEnumPetTypeMapping<PetEnum.Cat, CatWithEnum>
| BasePetWithEnumPetTypeMapping<PetEnum.Lizard, LizardWithEnum>
);

export type CatWithEnum = BasePetWithEnum & {
name?: string;
};
Expand All @@ -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. */
Expand Down Expand Up @@ -196,21 +196,18 @@ export interface VariantRollback {
/** asdasdasdasdasdn */
export type VariantUndo = object;

interface BaseBlockDtoWithEnum {
title: string;
type: BlockDTOEnum;
}
type BaseInvalidDiscriminatorPropertyName = object;

type BaseBlockDtoWithEnumTypeMapping<Key, Type> = {
type: Key;
type BaseInvalidDiscriminatorPropertyNameTypeMapping<Key, Type> = {
"@type": Key;
} & Type;

interface BaseBlockDto {
title: string;
interface BasePetWithEnum {
pet_type: PetEnum;
}

type BaseBlockDtoTypeMapping<Key, Type> = {
type: Key;
type BasePetWithEnumPetTypeMapping<Key, Type> = {
pet_type: Key;
} & Type;

interface BasePet {
Expand All @@ -221,18 +218,21 @@ type BasePetPetTypeMapping<Key, Type> = {
pet_type: Key;
} & Type;

interface BasePetWithEnum {
pet_type: PetEnum;
interface BaseBlockDto {
title: string;
}

type BasePetWithEnumPetTypeMapping<Key, Type> = {
pet_type: Key;
type BaseBlockDtoTypeMapping<Key, Type> = {
type: Key;
} & Type;

type BaseInvalidDiscriminatorPropertyName = object;
interface BaseBlockDtoWithEnum {
title: string;
type: BlockDTOEnum;
}

type BaseInvalidDiscriminatorPropertyNameTypeMapping<Key, Type> = {
"@type": Key;
type BaseBlockDtoWithEnumTypeMapping<Key, Type> = {
type: Key;
} & Type;
"
`;
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ export enum ExampleEnum {
Example2 = "Example2",
}

export type ExampleObject = BaseExampleObject &
(
| BaseExampleObjectTypeMapping<ExampleEnum.Example1, DtoExample1>
| BaseExampleObjectTypeMapping<ExampleEnum.Example2, DtoExample2>
);

export interface DtoExample1 {
name: string;
age: number;
Expand All @@ -29,12 +35,6 @@ export interface DtoExample2 {
description: string;
}

export type ExampleObject = BaseExampleObject &
(
| BaseExampleObjectTypeMapping<ExampleEnum.Example1, DtoExample1>
| BaseExampleObjectTypeMapping<ExampleEnum.Example2, DtoExample2>
);

interface BaseExampleObject {
type?: ExampleEnum;
}
Expand Down