Skip to content

Commit

Permalink
Correctly construct LiteralTypes for properties that are "const" (#559)
Browse files Browse the repository at this point in the history
* Added tests to check defintion of const properties

* fixed typo

* Added first draft of "const" assertion detection in TypeGenerator

* Correctly define LiteralType for const properties

---------

Co-authored-by: Hendrik Lücke-Tieke <[email protected]>
  • Loading branch information
helt and Hendrik Lücke-Tieke authored Oct 26, 2023
1 parent 7c4a415 commit bd3939b
Show file tree
Hide file tree
Showing 4 changed files with 157 additions and 0 deletions.
65 changes: 65 additions & 0 deletions packages/swagger-ts/mocks/discriminator.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
info:
title: Swagger Petstore
openapi: 3.1.0
components:
schemas:
Cat:
title: Cat
type: object
properties:
id:
format: uuid
title: Id
type: string
type:
const: Cat
title: Type
meow:
type: boolean
title: Meowing prevalence
required:
- id
- type
Dog:
title: Dog
type: object
properties:
id:
format: uuid
title: Id
type: string
bark:
type: number
title: Barking frequency
type:
const: Dog
title: Type
required:
- id
- type
Petstore:
title: Petstore
type: object
description: A project is an analysis project. It has a name, an id, and has
a dataset
properties:
id:
title: Id
type: integer
pets:
default: []
items:
discriminator:
mapping:
Cat: "#/components/schemas/Cat"
Dog: "#/components/schemas/Dog"
propertyName: type
oneOf:
- "$ref": "#/components/schemas/Cat"
- "$ref": "#/components/schemas/Dog"
title: Pets
type: array
required:
- id

paths:
60 changes: 60 additions & 0 deletions packages/swagger-ts/src/generators/TypeGenerator.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -182,3 +182,63 @@ describe('TypeGenerator with refs', () => {

test.todo('generate type for Pets and Pet')
})

describe('TypeGenerator with discriminators', () => {
const path = pathParser.resolve(__dirname, "../../mocks/discriminator.yaml")

test('PetStore defined as array with type union', async () => {
const oas = await oasPathParser(path)
const generator = new TypeGenerator({
withJSDocs: false,
resolveName: ({ name }) => name,
enumType: 'asConst',
dateType: 'string',
optionalType: 'questionToken',
})

const schemas = oas.getDefinition().components?.schemas
const node = generator.build({ schema: schemas?.Petstore as OpenAPIV3.SchemaObject, baseName: 'Petstore' })

const output = print(node, undefined)

expect(output).toBeDefined()
expect(output).toMatchSnapshot()
})

test('Cat.type defined as const', async () => {
const oas = await oasPathParser(path)
const generator = new TypeGenerator({
withJSDocs: false,
resolveName: ({ name }) => name,
enumType: 'asConst',
dateType: 'string',
optionalType: 'questionToken',
})

const schemas = oas.getDefinition().components?.schemas
const cat = generator.build({ schema: schemas?.Cat as OpenAPIV3.SchemaObject, baseName: 'Cat' })

const cat_output = print(cat, undefined)
expect(cat_output).toBeDefined()
expect(cat_output).toMatchSnapshot()
})

test('Dog.type defined as const', async () => {
const oas = await oasPathParser(path)
const generator = new TypeGenerator({
withJSDocs: false,
resolveName: ({ name }) => name,
enumType: 'asConst',
dateType: 'string',
optionalType: 'questionToken',
})

const schemas = oas.getDefinition().components?.schemas
const dog = generator.build({ schema: schemas?.Dog as OpenAPIV3.SchemaObject, baseName: 'Dog' })

const dog_output = print(dog, undefined)
expect(dog_output).toBeDefined()
expect(dog_output).toMatchSnapshot()
})

})
5 changes: 5 additions & 0 deletions packages/swagger-ts/src/generators/TypeGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,11 @@ export class TypeGenerator extends SchemaGenerator<Options, OpenAPIV3.SchemaObje
return factory.createTypeReferenceNode('Blob', [])
}

// detect assertion "const" and define the type property as a Literal
if("const" in schema && schema["const"] !== undefined && typeof schema["const"] === "string") {
return factory.createLiteralTypeNode(factory.createStringLiteral(schema["const"]));
}

return keywordTypeNodes.any
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`TypeGenerator with discriminators > Cat.type defined as const 1`] = `
"export type Cat = {
id: string;
type: \\"Cat\\";
meow?: boolean;
};
"
`;

exports[`TypeGenerator with discriminators > Dog.type defined as const 1`] = `
"export type Dog = {
id: string;
bark?: number;
type: \\"Dog\\";
};
"
`;

exports[`TypeGenerator with discriminators > PetStore defined as array with type union 1`] = `
"export type Petstore = {
id: number;
pets?: (Cat | Dog)[];
};
"
`;

1 comment on commit bd3939b

@vercel
Copy link

@vercel vercel bot commented on bd3939b Oct 26, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

kubb – ./

kubb-kubb.vercel.app
kubb-git-main-kubb.vercel.app
kubb.dev
www.kubb.dev

Please sign in to comment.