typespec
typespec copied to clipboard
tsp-openapi3 - allOf with more than one member not supported
Describe the bug
Currently tsp-openapi3 only includes allOf members in a generated TypeSpec model if there is one referenced member. In this case, the generated model extends the allOf member.
Instead the default behavior should be that all allOf members are spread into the generated TypeSpec model.
We may also need to support extending one of the allOf members if all of the following is true:
- One and only one of the members has a discriminator
- The discriminated member is a reference and not an in-line schema
Reproduction
openapi: 3.0.0
info:
title: Sample
version: 0.0.0
tags: []
paths: {}
components:
schemas:
Cat:
allOf:
- $ref: "#/components/schemas/Pet"
- type: object
required:
- kind
- name
properties:
kind:
type: string
enum:
- cat
name:
type: string
Pet:
type: object
required:
- kind
properties:
kind:
type: string
discriminator:
propertyName: kind
mapping:
cat: "#/components/schemas/Cat"
currently generates
import "@typespec/http";
import "@typespec/openapi";
import "@typespec/openapi3";
using Http;
using OpenAPI;
@service({
title: "Sample",
})
@info({
version: "0.0.0",
})
namespace Sample;
model Cat {}
@discriminator("kind")
model Pet {
kind: string;
}
The Cat model is empty since more than 1 allOf is not supported. However, if the in-lined schema was moved from Cat's allOf to the schema's root:
openapi: 3.0.0
info:
title: Sample
version: 0.0.0
tags: []
paths: {}
components:
schemas:
Cat:
type: object
required:
- kind
- name
properties:
kind:
type: string
enum:
- cat
name:
type: string
allOf:
- $ref: "#/components/schemas/Pet"
Pet:
type: object
required:
- kind
properties:
kind:
type: string
discriminator:
propertyName: kind
mapping:
cat: "#/components/schemas/Cat"
then the correct output is generated:
import "@typespec/http";
import "@typespec/openapi";
import "@typespec/openapi3";
using Http;
using OpenAPI;
@service({
title: "Sample",
})
@info({
version: "0.0.0",
})
namespace Sample;
model Cat extends Pet {
kind: "cat";
name: string;
}
@discriminator("kind")
model Pet {
kind: string;
}
Checklist
- [X] Follow our Code of Conduct
- [X] Check that there isn't already an issue that request the same bug to avoid creating a duplicate.
- [X] Check that this is a concrete bug. For Q&A open a GitHub Discussion.
- [X] The provided reproduction is a minimal reproducible example of the bug.