Fix handling decorators for union variants in JSONSchema emitter (#3398)
Fixes #3391 Also refactored a minor problem of using a deprecated reexport of `DuplicateTracker`, not it's referenced from `@typespec/compiler/utils` directly, and another small typo. --------- Co-authored-by: Timothee Guerin <timothee.guerin@outlook.com> Co-authored-by: Timothee Guerin <tiguerin@microsoft.com>
This commit is contained in:
Родитель
d14b0d7b63
Коммит
ccd67cf071
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
# Change versionKind to one of: internal, fix, dependencies, feature, deprecation, breaking
|
||||
changeKind: internal
|
||||
packages:
|
||||
- "@typespec/compiler"
|
||||
---
|
||||
Doc
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
# Change versionKind to one of: internal, fix, dependencies, feature, deprecation, breaking
|
||||
changeKind: fix
|
||||
packages:
|
||||
- "@typespec/json-schema"
|
||||
---
|
||||
|
||||
Fix decorators application for union variants
|
|
@ -118,7 +118,7 @@ export type EmitterOutput<T> = EmitEntity<T> | Placeholder<T> | T;
|
|||
* literals, and any type referenced inside anywhere inside the model and any
|
||||
* of the referenced types' references.
|
||||
*
|
||||
* In both cases, context is an object. It strongly recommended that the context
|
||||
* In both cases, context is an object. It's strongly recommended that the context
|
||||
* object either contain only primitive types, or else only reference immutable
|
||||
* objects.
|
||||
*
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import {
|
||||
BooleanLiteral,
|
||||
DiagnosticTarget,
|
||||
DuplicateTracker,
|
||||
Enum,
|
||||
EnumMember,
|
||||
IntrinsicType,
|
||||
|
@ -52,6 +51,7 @@ import {
|
|||
SourceFileScope,
|
||||
TypeEmitter,
|
||||
} from "@typespec/compiler/emitter-framework";
|
||||
import { DuplicateTracker } from "@typespec/compiler/utils";
|
||||
import { stringify } from "yaml";
|
||||
import {
|
||||
JsonSchemaDeclaration,
|
||||
|
@ -328,7 +328,14 @@ export class JsonSchemaEmitter extends TypeEmitter<Record<string, any>, JSONSche
|
|||
}
|
||||
|
||||
unionVariant(variant: UnionVariant): EmitterOutput<object> {
|
||||
return this.emitter.emitTypeReference(variant.type);
|
||||
const variantType = this.emitter.emitTypeReference(variant.type);
|
||||
compilerAssert(variantType.kind === "code", "Unexpected non-code result from emit reference");
|
||||
|
||||
const result = new ObjectBuilder(variantType.value);
|
||||
|
||||
this.#applyConstraints(variant, result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
modelPropertyReference(property: ModelProperty): EmitterOutput<object> {
|
||||
|
@ -513,7 +520,7 @@ export class JsonSchemaEmitter extends TypeEmitter<Record<string, any>, JSONSche
|
|||
}
|
||||
|
||||
#applyConstraints(
|
||||
type: Scalar | Model | ModelProperty | Union | Enum,
|
||||
type: Scalar | Model | ModelProperty | Union | UnionVariant | Enum,
|
||||
schema: ObjectBuilder<unknown>
|
||||
) {
|
||||
const applyConstraint = (fn: (p: Program, t: Type) => any, key: string) => {
|
||||
|
|
|
@ -87,4 +87,39 @@ describe("emitting unions", () => {
|
|||
const Foo = schemas["Foo.json"];
|
||||
assert.strictEqual(Foo["x-foo"], true);
|
||||
});
|
||||
|
||||
it("handles decorators on variants", async () => {
|
||||
const schemas = await emitSchema(`
|
||||
union Foo {
|
||||
@doc("doc text")
|
||||
@summary("summary text")
|
||||
@extension("x-key", Json<"x-value">)
|
||||
bar: string;
|
||||
|
||||
@doc("other model doc")
|
||||
@summary("other model summary")
|
||||
@extension("x-key-2", Json<"x-value-2">)
|
||||
baz: OtherModel;
|
||||
}
|
||||
|
||||
model OtherModel {}
|
||||
`);
|
||||
|
||||
const Foo = schemas["Foo.json"];
|
||||
|
||||
assert.deepStrictEqual(Foo.anyOf, [
|
||||
{
|
||||
description: "doc text",
|
||||
title: "summary text",
|
||||
type: "string",
|
||||
"x-key": "x-value",
|
||||
},
|
||||
{
|
||||
$ref: "OtherModel.json",
|
||||
description: "other model doc",
|
||||
title: "other model summary",
|
||||
"x-key-2": "x-value-2",
|
||||
},
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
|
Загрузка…
Ссылка в новой задаче