From 2f896c7703dd47a4ca02c96a9da2b235a7a27334 Mon Sep 17 00:00:00 2001 From: Kyle Zhang Date: Wed, 30 Oct 2024 07:50:04 +0800 Subject: [PATCH] The description parameter of @server should be optional (#4804) https://github.com/microsoft/typespec/issues/2229 --------- Co-authored-by: Kyle Zhang Co-authored-by: Timothee Guerin --- .../serverDescOption-2024-9-21-17-14-49.md | 7 +++++ docs/libraries/http/reference/decorators.md | 10 ++++++- packages/http/README.md | 10 ++++++- packages/http/generated-defs/TypeSpec.Http.ts | 9 +++++- packages/http/lib/decorators.tsp | 10 ++++++- packages/http/src/decorators.ts | 10 ++----- packages/http/test/http-decorators.test.ts | 28 +++++++++++-------- packages/openapi3/test/servers.test.ts | 18 +++++++++++- 8 files changed, 78 insertions(+), 24 deletions(-) create mode 100644 .chronus/changes/serverDescOption-2024-9-21-17-14-49.md diff --git a/.chronus/changes/serverDescOption-2024-9-21-17-14-49.md b/.chronus/changes/serverDescOption-2024-9-21-17-14-49.md new file mode 100644 index 0000000000..8bf296bdd2 --- /dev/null +++ b/.chronus/changes/serverDescOption-2024-9-21-17-14-49.md @@ -0,0 +1,7 @@ +--- +changeKind: fix +packages: + - "@typespec/http" +--- + +The description parameter of `@server` is now optional. \ No newline at end of file diff --git a/docs/libraries/http/reference/decorators.md b/docs/libraries/http/reference/decorators.md index d4f2a49f0e..bc5785cfac 100644 --- a/docs/libraries/http/reference/decorators.md +++ b/docs/libraries/http/reference/decorators.md @@ -412,7 +412,7 @@ Defines the relative route URI template for the target operation as defined by [ Specify an endpoint for this service. Multiple `@server` decorators can be used to specify multiple endpoints. ```typespec -@TypeSpec.Http.server(url: valueof string, description: valueof string, parameters?: Record) +@TypeSpec.Http.server(url: valueof string, description?: valueof string, parameters?: Record) ``` #### Target @@ -429,6 +429,14 @@ Specify an endpoint for this service. Multiple `@server` decorators can be used #### Examples +```typespec +@service +@server("https://example.com") +namespace PetStore; +``` + +##### With a description + ```typespec @service @server("https://example.com", "Single server endpoint") diff --git a/packages/http/README.md b/packages/http/README.md index f96ba37e1a..2283e4ff23 100644 --- a/packages/http/README.md +++ b/packages/http/README.md @@ -460,7 +460,7 @@ Defines the relative route URI template for the target operation as defined by [ Specify an endpoint for this service. Multiple `@server` decorators can be used to specify multiple endpoints. ```typespec -@TypeSpec.Http.server(url: valueof string, description: valueof string, parameters?: Record) +@TypeSpec.Http.server(url: valueof string, description?: valueof string, parameters?: Record) ``` ##### Target @@ -477,6 +477,14 @@ Specify an endpoint for this service. Multiple `@server` decorators can be used ##### Examples +```typespec +@service +@server("https://example.com") +namespace PetStore; +``` + +###### With a description + ```typespec @service @server("https://example.com", "Single server endpoint") diff --git a/packages/http/generated-defs/TypeSpec.Http.ts b/packages/http/generated-defs/TypeSpec.Http.ts index 9549772607..75eb5e9a59 100644 --- a/packages/http/generated-defs/TypeSpec.Http.ts +++ b/packages/http/generated-defs/TypeSpec.Http.ts @@ -215,6 +215,13 @@ export type HeadDecorator = (context: DecoratorContext, target: Operation) => vo * @example * ```typespec * @service + * @server("https://example.com") + * namespace PetStore; + * ``` + * @example With a description + * + * ```typespec + * @service * @server("https://example.com", "Single server endpoint") * namespace PetStore; * ``` @@ -240,7 +247,7 @@ export type ServerDecorator = ( context: DecoratorContext, target: Namespace, url: string, - description: string, + description?: string, parameters?: Type, ) => void; diff --git a/packages/http/lib/decorators.tsp b/packages/http/lib/decorators.tsp index 22267a2086..2a969214a9 100644 --- a/packages/http/lib/decorators.tsp +++ b/packages/http/lib/decorators.tsp @@ -270,6 +270,14 @@ extern dec head(target: Operation); * * ```typespec * @service + * @server("https://example.com") + * namespace PetStore; + * ``` + * + * @example With a description + * + * ```typespec + * @service * @server("https://example.com", "Single server endpoint") * namespace PetStore; * ``` @@ -297,7 +305,7 @@ extern dec head(target: Operation); extern dec server( target: Namespace, url: valueof string, - description: valueof string, + description?: valueof string, parameters?: Record ); diff --git a/packages/http/src/decorators.ts b/packages/http/src/decorators.ts index 5f9e089c72..d052a81c7f 100644 --- a/packages/http/src/decorators.ts +++ b/packages/http/src/decorators.ts @@ -419,7 +419,7 @@ const VERB_DECORATORS = [$get, $head, $post, $put, $patch, $delete]; export interface HttpServer { url: string; - description: string; + description?: string; parameters: Map; } @@ -434,7 +434,7 @@ export const $server: ServerDecorator = ( context: DecoratorContext, target: Namespace, url: string, - description: string, + description?: string, parameters?: Type, ) => { const params = extractParamsFromPath(url); @@ -456,11 +456,7 @@ export const $server: ServerDecorator = ( servers = []; context.program.stateMap(HttpStateKeys.servers).set(target, servers); } - servers.push({ - url, - description, - parameters: parameterMap, - }); + servers.push({ url, description, parameters: parameterMap }); }; export function getServers(program: Program, type: Namespace): HttpServer[] | undefined { diff --git a/packages/http/test/http-decorators.test.ts b/packages/http/test/http-decorators.test.ts index 8fe4350af6..6b8bb03621 100644 --- a/packages/http/test/http-decorators.test.ts +++ b/packages/http/test/http-decorators.test.ts @@ -638,18 +638,6 @@ describe("http: decorators", () => { }); }); - it("emit diagnostics when description is not provided", async () => { - const diagnostics = await runner.diagnose(` - @server("https://example.com") - namespace MyService {} - `); - - expectDiagnostics(diagnostics, { - code: "invalid-argument-count", - message: "Expected 2-3 arguments, but got 1.", - }); - }); - it("emit diagnostics when parameters is not a model", async () => { const diagnostics = await runner.diagnose(` @server("https://example.com", "My service url", 123) @@ -673,6 +661,22 @@ describe("http: decorators", () => { }); }); + it("define a simple server without description", async () => { + const { MyService } = (await runner.compile(` + @server("https://example.com") + @test namespace MyService {} + `)) as { MyService: Namespace }; + + const servers = getServers(runner.program, MyService); + deepStrictEqual(servers, [ + { + description: undefined, + parameters: new Map(), + url: "https://example.com", + }, + ]); + }); + it("define a simple server with a fixed url", async () => { const { MyService } = (await runner.compile(` @server("https://example.com", "My service url") diff --git a/packages/openapi3/test/servers.test.ts b/packages/openapi3/test/servers.test.ts index 38e82e4382..7807b609b3 100644 --- a/packages/openapi3/test/servers.test.ts +++ b/packages/openapi3/test/servers.test.ts @@ -4,7 +4,23 @@ import { describe, it } from "vitest"; import { diagnoseOpenApiFor, openApiFor } from "./test-host.js"; describe("openapi3: servers", () => { - it("set a basic server", async () => { + it("set a basic server(url)", async () => { + const res = await openApiFor( + ` + @service({title: "My service"}) + @server("https://example.com") + namespace MyService {} + `, + ); + deepStrictEqual(res.servers, [ + { + url: "https://example.com", + variables: {}, + }, + ]); + }); + + it("set a basic server(url and desc)", async () => { const res = await openApiFor( ` @service({title: "My service"})