Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

@summary sets the title of definitions #813

Merged
merged 8 commits into from
May 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .chronus/changes/summary-is-title-2024-4-9-20-35-33.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
# Change versionKind to one of: internal, fix, dependencies, feature, deprecation, breaking
changeKind: feature
packages:
- "@azure-tools/typespec-autorest"
---

`@summary` sets the title of definitions
33 changes: 24 additions & 9 deletions packages/typespec-autorest/src/openapi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import {
Value,
compilerAssert,
createDiagnosticCollector,
explainStringTemplateNotSerializable,
getAllTags,
getDirectoryPath,
getDiscriminator,
Expand Down Expand Up @@ -84,7 +85,6 @@ import {
navigateTypesInNamespace,
resolveEncodedName,
resolvePath,
stringTemplateToString,
} from "@typespec/compiler";
import { TwoLevelMap } from "@typespec/compiler/utils";
import {
Expand Down Expand Up @@ -1566,7 +1566,7 @@ export async function getOpenAPIForService(
modelSchema.required = [propertyName];
}
}

applySummary(model, modelSchema);
applyExternalDocs(model, modelSchema);

for (const prop of model.properties.values()) {
Expand All @@ -1589,7 +1589,6 @@ export async function getOpenAPIForService(
const clientName = getClientName(context, prop);

const description = getDoc(program, prop);

// if this property is a discriminator property, remove it to keep autorest validation happy
if (model.baseModel) {
const { propertyName } = getDiscriminator(program, model.baseModel) || {};
Expand Down Expand Up @@ -1617,6 +1616,7 @@ export async function getOpenAPIForService(
if (description) {
property.description = description;
}
applySummary(prop, property);

if (prop.defaultValue && !("$ref" in property)) {
property.default = getDefaultValue(prop.defaultValue);
Expand Down Expand Up @@ -1690,9 +1690,9 @@ export async function getOpenAPIForService(

function resolveProperty(prop: ModelProperty, context: SchemaContext): OpenAPI2SchemaProperty {
let propSchema;
if (prop.type.kind === "Enum" && prop.default) {
if (prop.type.kind === "Enum" && prop.defaultValue) {
timotheeguerin marked this conversation as resolved.
Show resolved Hide resolved
propSchema = getSchemaForEnum(prop.type);
} else if (prop.type.kind === "Union" && prop.default) {
} else if (prop.type.kind === "Union" && prop.defaultValue) {
const [asEnum, _] = getUnionAsEnum(prop.type);
if (asEnum) {
propSchema = getSchemaForUnionEnum(prop.type, asEnum);
Expand Down Expand Up @@ -1758,6 +1758,11 @@ export async function getOpenAPIForService(
newTarget.description = docStr;
}

const title = getSummary(program, typespecType);
if (title) {
target.title = title;
}

const formatStr = getFormat(program, typespecType);
if (isString && formatStr) {
const allowedStringFormats = [
Expand Down Expand Up @@ -1903,6 +1908,12 @@ export async function getOpenAPIForService(
}
}

function applySummary(typespecType: Type, target: { title?: string }) {
const summary = getSummary(program, typespecType);
if (summary) {
target.title = summary;
}
}
function applyExternalDocs(typespecType: Type, target: Record<string, unknown>) {
const externalDocs = getExternalDocs(program, typespecType);
if (externalDocs) {
Expand Down Expand Up @@ -1949,12 +1960,16 @@ export async function getOpenAPIForService(
}

function getSchemaForStringTemplate(stringTemplate: StringTemplate) {
const [value, diagnostics] = stringTemplateToString(stringTemplate);
if (diagnostics.length > 0) {
program.reportDiagnostics(diagnostics.map((x) => ({ ...x, severity: "warning" })));
if (stringTemplate.stringValue === undefined) {
program.reportDiagnostics(
explainStringTemplateNotSerializable(stringTemplate).map((x) => ({
...x,
severity: "warning",
}))
);
return { type: "string" };
}
return { type: "string", enum: [value] };
return { type: "string", enum: [stringTemplate.stringValue] };
}
// Map an TypeSpec type to an OA schema. Returns undefined when the resulting
// OA schema is just a regular object schema.
Expand Down
2 changes: 1 addition & 1 deletion packages/typespec-autorest/src/openapi2-document.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ export type JsonType = "array" | "boolean" | "integer" | "number" | "object" | "
* Autorest allows a few properties to be next to $ref of a property.
*/
export type OpenAPI2SchemaRefProperty = Ref<OpenAPI2Schema> &
Pick<OpenAPI2Schema, "readOnly" | "description" | "default" | "x-ms-mutability"> & {
Pick<OpenAPI2Schema, "readOnly" | "description" | "default" | "x-ms-mutability" | "title"> & {
/**
* Provide a different name to be used in the client.
*/
Expand Down
15 changes: 15 additions & 0 deletions packages/typespec-autorest/test/models.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,21 @@ describe("typespec-autorest: model definitions", () => {
});
});

it("using @summary sets the title on definitions and properties", async () => {
const res = await oapiForModel(
"Foo",
`
@summary("FooModel")
model Foo {
@summary("YProp")
y: int32;
};
`
);
strictEqual(res.defs.Foo.title, "FooModel");
strictEqual(res.defs.Foo.properties.y.title, "YProp");
});

it("uses json name specified via @encodedName", async () => {
const res = await oapiForModel(
"Foo",
Expand Down
Loading