Skip to content

Commit 8c09769

Browse files
Support externalDocs on properties (#3558)
fix #3509 Same pr for openapi3 microsoft/typespec#9076
1 parent 404f46f commit 8c09769

File tree

4 files changed

+66
-27
lines changed

4 files changed

+66
-27
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
changeKind: fix
3+
packages:
4+
- "@azure-tools/typespec-autorest"
5+
---
6+
7+
Respect `@externalDocs` on properties

packages/typespec-autorest/src/openapi.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ import { createDiagnostic, reportDiagnostic } from "./lib.js";
153153
import {
154154
OpenAPI2BodyParameter,
155155
OpenAPI2Document,
156+
OpenAPI2ExternalDocs,
156157
OpenAPI2FileSchema,
157158
OpenAPI2HeaderDefinition,
158159
OpenAPI2HeaderParameter,
@@ -2040,7 +2041,7 @@ export async function getOpenAPIForService(
20402041
if (prop.defaultValue && !("$ref" in property)) {
20412042
property.default = getDefaultValue(prop.defaultValue, prop);
20422043
}
2043-
2044+
applyExternalDocs(prop, property);
20442045
if (isReadonlyProperty(program, prop)) {
20452046
property.readOnly = true;
20462047
} else {
@@ -2458,7 +2459,7 @@ export async function getOpenAPIForService(
24582459
target.title = summary;
24592460
}
24602461
}
2461-
function applyExternalDocs(typespecType: Type, target: Record<string, unknown>) {
2462+
function applyExternalDocs(typespecType: Type, target: { externalDocs?: OpenAPI2ExternalDocs }) {
24622463
const externalDocs = getExternalDocs(program, typespecType);
24632464
if (externalDocs) {
24642465
target.externalDocs = externalDocs;

packages/typespec-autorest/src/openapi2-document.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ export type JsonType = "array" | "boolean" | "integer" | "number" | "object" | "
112112
export type OpenAPI2SchemaRefProperty = Ref<OpenAPI2Schema> &
113113
Pick<
114114
OpenAPI2Schema,
115-
"readOnly" | "description" | "default" | "x-ms-mutability" | "title" | "xml"
115+
"readOnly" | "description" | "default" | "x-ms-mutability" | "title" | "xml" | "externalDocs"
116116
> & {
117117
/**
118118
* Provide a different name to be used in the client.
@@ -291,6 +291,9 @@ export type OpenAPI2Schema = Extensions & {
291291
* XML metadata for the schema, if applicable.
292292
*/
293293
xml?: XmlObject;
294+
295+
/** Additional external documentation. */
296+
externalDocs?: OpenAPI2ExternalDocs;
294297
};
295298

296299
export interface XmlObject {
Lines changed: 52 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,69 @@
11
import { deepStrictEqual, strictEqual } from "assert";
2-
import { describe, it } from "vitest";
2+
import { expect, it } from "vitest";
33
import { openApiFor } from "./test-host.js";
44

5-
describe("typespec-autorest: documentation", () => {
6-
it("supports summary and description", async () => {
7-
const openApi = await openApiFor(`
8-
@summary("This is a summary")
9-
@doc("This is the longer description")
10-
op read(): {};
11-
`);
12-
strictEqual(openApi.paths["/"].get.summary, "This is a summary");
13-
strictEqual(openApi.paths["/"].get.description, "This is the longer description");
5+
it("supports summary and description", async () => {
6+
const openApi = await openApiFor(`
7+
@summary("This is a summary")
8+
@doc("This is the longer description")
9+
op read(): {};
10+
`);
11+
strictEqual(openApi.paths["/"].get.summary, "This is a summary");
12+
strictEqual(openApi.paths["/"].get.description, "This is the longer description");
13+
});
14+
15+
it("supports externalDocs on operation", async () => {
16+
const openApi = await openApiFor(`
17+
@externalDocs("https://example.com", "more info")
18+
op read(): {};
19+
`);
20+
deepStrictEqual(openApi.paths["/"].get.externalDocs, {
21+
url: "https://example.com",
22+
description: "more info",
1423
});
24+
});
25+
26+
it("supports externalDocs on models", async () => {
27+
const openApi = await openApiFor(`
28+
@externalDocs("https://example.com", "more info")
29+
model Foo {
30+
name: string;
31+
}
32+
`);
33+
deepStrictEqual(openApi.definitions.Foo.externalDocs, {
34+
url: "https://example.com",
35+
description: "more info",
36+
});
37+
});
1538

16-
it("supports externalDocs on operation", async () => {
17-
const openApi = await openApiFor(`
39+
it("supports externalDocs on properties", async () => {
40+
const openApi = await openApiFor(`
41+
model Foo {
1842
@externalDocs("https://example.com", "more info")
19-
op read(): {};
43+
name: string;
44+
}
2045
`);
21-
deepStrictEqual(openApi.paths["/"].get.externalDocs, {
46+
expect(openApi.definitions.Foo.properties.name).toEqual({
47+
type: "string",
48+
externalDocs: {
2249
url: "https://example.com",
2350
description: "more info",
24-
});
51+
},
2552
});
26-
27-
it("supports externalDocs on models", async () => {
28-
const openApi = await openApiFor(`
29-
op read(): Foo;
30-
31-
@externalDocs("https://example.com", "more info")
53+
});
54+
it("supports externalDocs on properties resulting in a $ref", async () => {
55+
const openApi = await openApiFor(`
3256
model Foo {
33-
name: string;
57+
@externalDocs("https://example.com", "more info")
58+
name: Bar;
3459
}
60+
model Bar {}
3561
`);
36-
deepStrictEqual(openApi.definitions.Foo.externalDocs, {
62+
expect(openApi.definitions.Foo.properties.name).toEqual({
63+
$ref: "#/definitions/Bar",
64+
externalDocs: {
3765
url: "https://example.com",
3866
description: "more info",
39-
});
67+
},
4068
});
4169
});

0 commit comments

Comments
 (0)