feat(swagger): support raw component schemas - #3914
Conversation
|
could you please target v12.0.0? |
7234c1e to
02c3b62
Compare
|
@kamilmysliwiec we don't have v12.0.0 on this repo Rebased and retargeted this PR to |
02c3b62 to
1217e3f
Compare
|
could you update e2e tests as well? |
|
Done! |
|
I think this is solving a named schema registration problem rather than a type modeling problem. Using an empty class as a placeholder is misleading because it makes Because For example: @ApiSchema({
name: 'Pet',
oneOf: [
{ $ref: getSchemaPath(CatDto) },
{ $ref: getSchemaPath(DogDto) },
],
discriminator: {
propertyName: 'type',
mapping: {
cat: getSchemaPath(CatDto),
dog: getSchemaPath(DogDto),
},
},
})
class PetDto {}The actual application type still needs to be declared separately: type PetDto = CatDto | DogDto;Would it make more sense to expose a helper for registering a named const PetApiSchema = defineApiSchema('Pet', {
oneOf: [
{ $ref: getSchemaPath(CatDto) },
{ $ref: getSchemaPath(DogDto) },
],
discriminator: {
propertyName: 'type',
mapping: {
cat: getSchemaPath(CatDto),
dog: getSchemaPath(DogDto),
},
},
});The helper could accept the standard OpenAPI There is already a similar precedent in A similar helper here would keep the responsibilities clear:
This seems more consistent with the existing NestJS approach to schema-level constructs and avoids overloading DTO classes with schema-registration semantics. |
PR Checklist
Please check if your PR fulfills the following requirements:
PR Type
What kind of change does this PR introduce?
What is the current behavior?
@ApiSchema()metadata is always merged into a generated object schema. Even when a class-level schema declaresoneOf,anyOf, orallOf, the resultingcomponents.schemasentry still gets generated object scaffolding such astype: 'object'andproperties: {}.This prevents using a class-level placeholder as a raw top-level component schema for cases like
oneOfplusdiscriminator.mapping.Issue Number: Fixes #3886
What is the new behavior?
@ApiSchema()now accepts the fullSchemaObjectshape. When a class-level schema declaresoneOf,anyOf, orallOf,SchemaObjectFactoryregisters it as a raw top-level component schema instead of wrapping it in generated object metadata.This lets users define component schemas such as:
The existing object-schema behavior is preserved for regular DTOs and for
@ApiSchema()options without schema combinators.Does this PR introduce a breaking change?
Other information
Local checks:
npm test -- test/services/schema-object-factory.spec.tsnpm test -- test/explorer/swagger-explorer.spec.tsnpm run buildnpm run lint(passes with existing warnings outside this change)npm exec prettier -- --check lib/decorators/api-schema.decorator.ts lib/services/schema-object-factory.ts test/services/schema-object-factory.spec.ts test/explorer/swagger-explorer.spec.tsgit diff --checkNote: local Node is
v20.18.3, while some dependencies now warn for^20.19.0 || >=22.12.0. I installed missing optional native packages forrolldownandoxlintwithout changing the lockfile to run the checks.