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
|
* literals, and any type referenced inside anywhere inside the model and any
|
||||||
* of the referenced types' references.
|
* 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
|
* object either contain only primitive types, or else only reference immutable
|
||||||
* objects.
|
* objects.
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import {
|
import {
|
||||||
BooleanLiteral,
|
BooleanLiteral,
|
||||||
DiagnosticTarget,
|
DiagnosticTarget,
|
||||||
DuplicateTracker,
|
|
||||||
Enum,
|
Enum,
|
||||||
EnumMember,
|
EnumMember,
|
||||||
IntrinsicType,
|
IntrinsicType,
|
||||||
|
@ -52,6 +51,7 @@ import {
|
||||||
SourceFileScope,
|
SourceFileScope,
|
||||||
TypeEmitter,
|
TypeEmitter,
|
||||||
} from "@typespec/compiler/emitter-framework";
|
} from "@typespec/compiler/emitter-framework";
|
||||||
|
import { DuplicateTracker } from "@typespec/compiler/utils";
|
||||||
import { stringify } from "yaml";
|
import { stringify } from "yaml";
|
||||||
import {
|
import {
|
||||||
JsonSchemaDeclaration,
|
JsonSchemaDeclaration,
|
||||||
|
@ -328,7 +328,14 @@ export class JsonSchemaEmitter extends TypeEmitter<Record<string, any>, JSONSche
|
||||||
}
|
}
|
||||||
|
|
||||||
unionVariant(variant: UnionVariant): EmitterOutput<object> {
|
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> {
|
modelPropertyReference(property: ModelProperty): EmitterOutput<object> {
|
||||||
|
@ -513,7 +520,7 @@ export class JsonSchemaEmitter extends TypeEmitter<Record<string, any>, JSONSche
|
||||||
}
|
}
|
||||||
|
|
||||||
#applyConstraints(
|
#applyConstraints(
|
||||||
type: Scalar | Model | ModelProperty | Union | Enum,
|
type: Scalar | Model | ModelProperty | Union | UnionVariant | Enum,
|
||||||
schema: ObjectBuilder<unknown>
|
schema: ObjectBuilder<unknown>
|
||||||
) {
|
) {
|
||||||
const applyConstraint = (fn: (p: Program, t: Type) => any, key: string) => {
|
const applyConstraint = (fn: (p: Program, t: Type) => any, key: string) => {
|
||||||
|
|
|
@ -87,4 +87,39 @@ describe("emitting unions", () => {
|
||||||
const Foo = schemas["Foo.json"];
|
const Foo = schemas["Foo.json"];
|
||||||
assert.strictEqual(Foo["x-foo"], true);
|
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",
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
Загрузка…
Ссылка в новой задаче