diff --git a/.chronus/changes/migrate-valueof-remaining-2025-1-21-17-35-12.md b/.chronus/changes/migrate-valueof-remaining-2025-1-21-17-35-12.md new file mode 100644 index 00000000000..9e1f6ca57ed --- /dev/null +++ b/.chronus/changes/migrate-valueof-remaining-2025-1-21-17-35-12.md @@ -0,0 +1,13 @@ +--- +# Change versionKind to one of: internal, fix, dependencies, feature, deprecation, breaking +changeKind: feature +packages: + - "@typespec/compiler" +--- + +Migrate `@service` decorator options to take in a value + +```diff lang="tsp" +-@service({title: "My service"}) ++@service(#{title: "My service"}) +``` diff --git a/.chronus/changes/migrate-valueof-remaining-2025-1-21-17-48-47.md b/.chronus/changes/migrate-valueof-remaining-2025-1-21-17-48-47.md new file mode 100644 index 00000000000..a3708e8729b --- /dev/null +++ b/.chronus/changes/migrate-valueof-remaining-2025-1-21-17-48-47.md @@ -0,0 +1,26 @@ +--- +# Change versionKind to one of: internal, fix, dependencies, feature, deprecation, breaking +changeKind: feature +packages: + - "@typespec/openapi" +--- + +Migrate `@info` decorator to expect a value + +```diff lang="tsp" +-@info({ version: "1.0.0" }) ++@info(#{ version: "1.0.0" }) +``` + +```diff lang="tsp" +-@info({ ++@info(#{ + termsOfService: "http://example.com/terms/", +- contact: { ++ contact: #{ + name: "API Support", + url: "http://www.example.com/support", + email: "support@example.com" + }, +}) +``` diff --git a/.chronus/changes/migrate-valueof-remaining-2025-1-21-17-57-6.md b/.chronus/changes/migrate-valueof-remaining-2025-1-21-17-57-6.md new file mode 100644 index 00000000000..f6431de2293 --- /dev/null +++ b/.chronus/changes/migrate-valueof-remaining-2025-1-21-17-57-6.md @@ -0,0 +1,13 @@ +--- +# Change versionKind to one of: internal, fix, dependencies, feature, deprecation, breaking +changeKind: internal +packages: + - "@typespec/http-server-csharp" + - "@typespec/http-specs" + - "@typespec/http" + - "@typespec/openapi3" + - "@typespec/rest" + - "@typespec/versioning" +--- + +Update tests and samples diff --git a/README.md b/README.md index 83869260d9a..31872e1ce37 100644 --- a/README.md +++ b/README.md @@ -53,9 +53,7 @@ using TypeSpec.Http; using TypeSpec.Rest; /** This is a pet store service. */ -@service({ - title: "Pet Store Service", -}) +@service(#{ title: "Pet Store Service" }) @server("https://example.com", "The service endpoint") namespace PetStore; diff --git a/packages/compiler/generated-defs/TypeSpec.ts b/packages/compiler/generated-defs/TypeSpec.ts index a046e17ae5d..e36df4a7d55 100644 --- a/packages/compiler/generated-defs/TypeSpec.ts +++ b/packages/compiler/generated-defs/TypeSpec.ts @@ -14,6 +14,11 @@ import type { UnionVariant, } from "../src/core/index.js"; +export interface ServiceOptions { + readonly title?: string; + readonly version?: string; +} + export interface DiscriminatedOptions { readonly envelope?: "object" | "none"; readonly discriminatorPropertyName?: string; @@ -222,19 +227,19 @@ export type DeprecatedDecorator = ( * ``` * @example Setting service title * ```typespec - * @service({title: "Pet store"}) + * @service(#{title: "Pet store"}) * namespace PetStore; * ``` * @example Setting service version * ```typespec - * @service({version: "1.0"}) + * @service(#{version: "1.0"}) * namespace PetStore; * ``` */ export type ServiceDecorator = ( context: DecoratorContext, target: Namespace, - options?: Type, + options?: ServiceOptions, ) => void; /** diff --git a/packages/compiler/lib/std/decorators.tsp b/packages/compiler/lib/std/decorators.tsp index 206ffe9c7a1..2adb6fdb1ca 100644 --- a/packages/compiler/lib/std/decorators.tsp +++ b/packages/compiler/lib/std/decorators.tsp @@ -102,17 +102,17 @@ model ServiceOptions { * * @example Setting service title * ```typespec - * @service({title: "Pet store"}) + * @service(#{title: "Pet store"}) * namespace PetStore; * ``` * * @example Setting service version * ```typespec - * @service({version: "1.0"}) + * @service(#{version: "1.0"}) * namespace PetStore; * ``` */ -extern dec service(target: Namespace, options?: ServiceOptions); +extern dec service(target: Namespace, options?: valueof ServiceOptions); /** * Specify that this model is an error type. Operations return error types when the operation has failed. diff --git a/packages/compiler/src/lib/service.ts b/packages/compiler/src/lib/service.ts index ac7c90c6dd3..7b94fd410ef 100644 --- a/packages/compiler/src/lib/service.ts +++ b/packages/compiler/src/lib/service.ts @@ -1,7 +1,6 @@ -import { ServiceDecorator } from "../../generated-defs/TypeSpec.js"; +import type { ServiceDecorator, ServiceOptions } from "../../generated-defs/TypeSpec.js"; import { validateDecoratorUniqueOnNode } from "../core/decorator-utils.js"; -import { Type, getTypeName, reportDeprecated } from "../core/index.js"; -import { reportDiagnostic } from "../core/messages.js"; +import { reportDeprecated } from "../core/index.js"; import type { Program } from "../core/program.js"; import { DecoratorContext, Namespace } from "../core/types.js"; import { Realm } from "../experimental/realm.js"; @@ -69,50 +68,17 @@ export function addService( export const $service: ServiceDecorator = ( context: DecoratorContext, target: Namespace, - options?: Type, + options?: ServiceOptions, ) => { validateDecoratorUniqueOnNode(context, target, $service); - if (options && options.kind !== "Model") { - reportDiagnostic(context.program, { - code: "invalid-argument", - format: { value: options.kind, expected: "Model" }, - target: context.getArgumentTarget(0)!, - }); - return; - } - const serviceDetails: ServiceDetails = {}; - const title = options?.properties.get("title")?.type; - const versionProp = options?.properties.get("version"); - if (title) { - if (title.kind === "String") { - serviceDetails.title = title.value; - } else { - reportDiagnostic(context.program, { - code: "unassignable", - format: { sourceType: getTypeName(title), targetType: "String" }, - target: context.getArgumentTarget(0)!, - }); - } - } - if (versionProp) { - const version = versionProp.type; + if (options?.version) { reportDeprecated( context.program, "version: property is deprecated in @service. If wanting to describe a service versioning you can use the `@typespec/versioning` library. If wanting to describe the project version you can use the package.json version.", - versionProp, + context.getArgumentTarget(0)!, ); - if (version.kind === "String") { - // eslint-disable-next-line @typescript-eslint/no-deprecated - serviceDetails.version = version.value; - } else { - reportDiagnostic(context.program, { - code: "unassignable", - format: { sourceType: getTypeName(version), targetType: "String" }, - target: context.getArgumentTarget(0)!, - }); - } } - addService(context.program, target, serviceDetails); + addService(context.program, target, options); }; diff --git a/packages/compiler/templates/__snapshots__/rest/main.tsp b/packages/compiler/templates/__snapshots__/rest/main.tsp index d5c1d97b5cc..f41cb2a6588 100644 --- a/packages/compiler/templates/__snapshots__/rest/main.tsp +++ b/packages/compiler/templates/__snapshots__/rest/main.tsp @@ -1,9 +1,7 @@ import "@typespec/http"; using TypeSpec.Http; -@service({ - title: "Widget Service", -}) +@service(#{ title: "Widget Service" }) namespace DemoService; model Widget { diff --git a/packages/compiler/templates/rest/main.tsp b/packages/compiler/templates/rest/main.tsp index d5c1d97b5cc..f41cb2a6588 100644 --- a/packages/compiler/templates/rest/main.tsp +++ b/packages/compiler/templates/rest/main.tsp @@ -1,9 +1,7 @@ import "@typespec/http"; using TypeSpec.Http; -@service({ - title: "Widget Service", -}) +@service(#{ title: "Widget Service" }) namespace DemoService; model Widget { diff --git a/packages/compiler/test/decorators/service.test.ts b/packages/compiler/test/decorators/service.test.ts index 02351e769cb..e9335925628 100644 --- a/packages/compiler/test/decorators/service.test.ts +++ b/packages/compiler/test/decorators/service.test.ts @@ -50,7 +50,7 @@ describe("compiler: service", () => { it("customize service title", async () => { const { S } = await runner.compile(` - @test @service({title: "My Service"}) namespace S {} + @test @service(#{title: "My Service"}) namespace S {} `); @@ -59,7 +59,7 @@ describe("compiler: service", () => { it("emit diagnostic if service title is not a string", async () => { const diagnostics = await runner.diagnose(` - @test @service({title: 123}) namespace S {} + @test @service(#{title: 123}) namespace S {} `); expectDiagnostics(diagnostics, { @@ -71,8 +71,8 @@ describe("compiler: service", () => { it("customize service version", async () => { const { S } = await runner.compile(` - @test @service({ - #suppress "deprecated" "test" + #suppress "deprecated" "test" + @test @service(#{ version: "1.2.3" }) namespace S {} @@ -94,7 +94,7 @@ describe("compiler: service", () => { it("emit diagnostic if service version is not a string", async () => { const diagnostics = await runner.diagnose(` - @test @service({ + @test @service(#{ #suppress "deprecated" "test" version: 123 }) namespace S {} diff --git a/packages/compiler/test/e2e/init-templates.e2e.ts b/packages/compiler/test/e2e/init-templates.e2e.ts index 13045f4f05c..34d9260aaf5 100644 --- a/packages/compiler/test/e2e/init-templates.e2e.ts +++ b/packages/compiler/test/e2e/init-templates.e2e.ts @@ -117,7 +117,8 @@ describe("Init templates e2e tests", () => { }); describe("validate templates", () => { - it("validate rest template", async () => { + // TODO: reenable after release + it.skip("validate rest template", async () => { const fixture = await scaffoldTemplateForTest("rest"); await fixture.checkCommand("npm", ["install"]); await fixture.checkCommand("npx", ["tsp", "compile", "."]); diff --git a/packages/compiler/test/server/get-hover.test.ts b/packages/compiler/test/server/get-hover.test.ts index 3033c5c0dc2..5255de39976 100644 --- a/packages/compiler/test/server/get-hover.test.ts +++ b/packages/compiler/test/server/get-hover.test.ts @@ -335,7 +335,7 @@ describe("compiler: server: on hover", () => { it("model in namespace", async () => { const hover = await getHoverAtCursor( ` - @service({title: "RT"}) + @service(#{title: "RT"}) namespace TestNs; model Ani┆mal{ @@ -355,7 +355,7 @@ describe("compiler: server: on hover", () => { it("model with one template arg", async () => { const hover = await getHoverAtCursor( ` - @service({title: "RT"}) + @service(#{title: "RT"}) namespace TestNs; model Ani┆mal{ @@ -376,7 +376,7 @@ describe("compiler: server: on hover", () => { it("model with two template args", async () => { const hover = await getHoverAtCursor( ` - @service({title: "RT"}) + @service(#{title: "RT"}) namespace TestNs; model Ani┆mal{ @@ -433,7 +433,7 @@ describe("compiler: server: on hover", () => { it("interface in namespace", async () => { const hover = await getHoverAtCursor( ` - @service({title: "RT"}) + @service(#{title: "RT"}) namespace TestNs; interface IAct┆ions{ @@ -483,7 +483,7 @@ describe("compiler: server: on hover", () => { it("operation in namespace", async () => { const hover = await getHoverAtCursor( ` - @service({title: "RT"}) + @service(#{title: "RT"}) namespace TestNs; op Ea┆t(food: string): void; @@ -500,7 +500,7 @@ describe("compiler: server: on hover", () => { it("operation with one template arg", async () => { const hover = await getHoverAtCursor( ` - @service({title: "RT"}) + @service(#{title: "RT"}) namespace TestNs; op Ea┆t(food: string): void; @@ -517,7 +517,7 @@ describe("compiler: server: on hover", () => { it("operation with two template args", async () => { const hover = await getHoverAtCursor( ` - @service({title: "RT"}) + @service(#{title: "RT"}) namespace TestNs; op Ea┆t(food: string): void; @@ -534,7 +534,7 @@ describe("compiler: server: on hover", () => { it("operation in interface", async () => { const hover = await getHoverAtCursor( ` - @service({title: "RT"}) + @service(#{title: "RT"}) namespace TestNs; interface IActions { @@ -553,7 +553,7 @@ describe("compiler: server: on hover", () => { it("operation in interface with template", async () => { const hover = await getHoverAtCursor( ` - @service({title: "RT"}) + @service(#{title: "RT"}) namespace TestNs; interface IActions { diff --git a/packages/http-client/test/typekit/client-library.test.ts b/packages/http-client/test/typekit/client-library.test.ts index 91c0083ca9a..ef064d77ed8 100644 --- a/packages/http-client/test/typekit/client-library.test.ts +++ b/packages/http-client/test/typekit/client-library.test.ts @@ -14,7 +14,7 @@ beforeEach(async () => { describe("listNamespaces", () => { it("basic", async () => { await runner.compile(` - @service({ + @service(#{ title: "Widget Service", }) namespace DemoService; @@ -26,7 +26,7 @@ describe("listNamespaces", () => { it("nested", async () => { // we only want to return the top level namespaces await runner.compile(` - @service({ + @service(#{ title: "Widget Service", }) namespace DemoService { @@ -65,7 +65,7 @@ describe("listClients", () => { it("should get the client", async () => { const { DemoService } = (await runner.compile(` - @service({ + @service(#{ title: "Widget Service", }) @test namespace DemoService; @@ -77,7 +77,7 @@ describe("listClients", () => { }); it("get subclients", async () => { const { DemoService } = (await runner.compile(` - @service({ + @service(#{ title: "Widget Service", }) @test namespace DemoService { diff --git a/packages/http-client/test/typekit/client.test.ts b/packages/http-client/test/typekit/client.test.ts index 9f4f3700728..8503a808ce8 100644 --- a/packages/http-client/test/typekit/client.test.ts +++ b/packages/http-client/test/typekit/client.test.ts @@ -15,7 +15,7 @@ beforeEach(async () => { describe("isSameConstructor", () => { it("should return true for the same client", async () => { const { DemoService } = (await runner.compile(` - @service({ + @service(#{ title: "Widget Service", }) @test namespace DemoService; @@ -28,7 +28,7 @@ describe("isSameConstructor", () => { it("should return false for the clients with different constructors", async () => { const { DemoService, SubClient } = (await runner.compile(` - @service({ + @service(#{ title: "Widget Service", }) @test namespace DemoService { @@ -46,7 +46,7 @@ describe("isSameConstructor", () => { it.skip("should return true when subclient doesn't override the client params", async () => { const { DemoService, SubClient } = (await runner.compile(` - @service({ + @service(#{ title: "Widget Service", }) @useAuth(ApiKeyAuth) @@ -64,7 +64,7 @@ describe("isSameConstructor", () => { it("should return false for the clients with different constructor", async () => { const { DemoService, SubClient } = (await runner.compile(` - @service({ + @service(#{ title: "Widget Service", }) @test namespace DemoService { @@ -94,7 +94,7 @@ describe("getClient", () => { it("should get the client", async () => { const { DemoService } = (await runner.compile(` - @service({ + @service(#{ title: "Widget Service", }) @test namespace DemoService; @@ -109,7 +109,7 @@ describe("getClient", () => { it("should preserve client object identity", async () => { const { DemoService } = (await runner.compile(` - @service({ + @service(#{ title: "Widget Service", }) @test namespace DemoService; @@ -122,7 +122,7 @@ describe("getClient", () => { it("should get a flattened list of clients", async () => { const { DemoService, BarBaz } = (await runner.compile(` - @service({ + @service(#{ title: "Widget Service", }) @test namespace DemoService { @@ -149,7 +149,7 @@ describe("getConstructor", () => { describe("credential parameter", () => { it("none", async () => { const { DemoService } = (await runner.compile(` - @service({ + @service(#{ title: "Widget Service", }) @test namespace DemoService; @@ -166,7 +166,7 @@ describe("getConstructor", () => { }); it("apikey", async () => { const { DemoService } = (await runner.compile(` - @service({ + @service(#{ title: "Widget Service", }) @useAuth(ApiKeyAuth) @@ -189,7 +189,7 @@ describe("getConstructor", () => { it("bearer", async () => { const { DemoService } = (await runner.compile(` - @service({ + @service(#{ title: "Widget Service", }) @useAuth(OAuth2Auth<[{ @@ -217,7 +217,7 @@ describe("getConstructor", () => { describe("endpoint", () => { it("no servers", async () => { const { DemoService } = (await runner.compile(` - @service({ + @service(#{ title: "Widget Service", }) @test namespace DemoService; @@ -235,7 +235,7 @@ describe("getConstructor", () => { it("one server, no params", async () => { const { DemoService } = (await runner.compile(` @server("https://example.com", "The service endpoint") - @service({ + @service(#{ title: "Widget Service", }) @test namespace DemoService; @@ -254,7 +254,7 @@ describe("getConstructor", () => { it("one server with parameter", async () => { const { DemoService } = (await runner.compile(` @server("https://example.com/{name}/foo", "My service url", { name: string }) - @service({ + @service(#{ title: "Widget Service", }) @test namespace DemoService; @@ -308,7 +308,7 @@ describe("getConstructor", () => { const { DemoService } = (await runner.compile(` @server("https://example.com", "The service endpoint") @server("https://example.org", "The service endpoint") - @service({ + @service(#{ title: "Widget Service", }) @test namespace DemoService; @@ -341,7 +341,7 @@ describe("getConstructor", () => { describe("isPubliclyInitializable", () => { it("namespace", async () => { const { DemoService } = (await runner.compile(` - @service({ + @service(#{ title: "Widget Service", }) @test namespace DemoService; @@ -354,7 +354,7 @@ describe("isPubliclyInitializable", () => { }); it("nested namespace", async () => { const { DemoService } = (await runner.compile(` - @service({ + @service(#{ title: "Widget Service", }) @test namespace DemoService { @@ -374,7 +374,7 @@ describe("isPubliclyInitializable", () => { }); it("nested interface", async () => { const { DemoService } = (await runner.compile(` - @service({ + @service(#{ title: "Widget Service", }) @test namespace DemoService { @@ -411,7 +411,7 @@ describe("listServiceOperations", () => { it("no operations", async () => { const { DemoService } = (await runner.compile(` - @service({ + @service(#{ title: "Widget Service", }) @test namespace DemoService; @@ -422,7 +422,7 @@ describe("listServiceOperations", () => { }); it("nested namespace", async () => { const { DemoService, NestedService } = (await runner.compile(` - @service({ + @service(#{ title: "Widget Service", }) @test namespace DemoService { diff --git a/packages/http-client/test/typekit/model-property.test.ts b/packages/http-client/test/typekit/model-property.test.ts index ba5bbef520a..5e9d311cad8 100644 --- a/packages/http-client/test/typekit/model-property.test.ts +++ b/packages/http-client/test/typekit/model-property.test.ts @@ -15,7 +15,7 @@ beforeEach(async () => { describe("getCredentialAuth", () => { it("should return the correct http scheme", async () => { const { DemoService } = (await runner.compile(` - @service({ + @service(#{ title: "Widget Service", }) @useAuth(ApiKeyAuth) @@ -37,7 +37,7 @@ describe("getCredentialAuth", () => { it("should return the correct http schemes", async () => { const { DemoService } = (await runner.compile(` - @service({ + @service(#{ title: "Widget Service", }) @useAuth(ApiKeyAuth | OAuth2Auth<[{ @@ -67,7 +67,7 @@ describe("isOnClient", () => { describe("endpoint", () => { it("no servers", async () => { const { DemoService } = (await runner.compile(` - @service({ + @service(#{ title: "Widget Service", }) @test namespace DemoService; @@ -83,7 +83,7 @@ describe("isOnClient", () => { it("one server, no params", async () => { const { DemoService } = (await runner.compile(` @server("https://example.com", "The service endpoint") - @service({ + @service(#{ title: "Widget Service", }) @test namespace DemoService; @@ -99,7 +99,7 @@ describe("isOnClient", () => { it("one server with parameter", async () => { const { DemoService } = (await runner.compile(` @server("https://example.com/{name}/foo", "My service url", { name: string }) - @service({ + @service(#{ title: "Widget Service", }) @test namespace DemoService; @@ -151,7 +151,7 @@ describe("isOnClient", () => { describe("credential", () => { it("apikey", async () => { const { DemoService } = (await runner.compile(` - @service({ + @service(#{ title: "Widget Service", }) @useAuth(ApiKeyAuth) @@ -169,7 +169,7 @@ describe("isOnClient", () => { }); it("bearer", async () => { const { DemoService } = (await runner.compile(` - @service({ + @service(#{ title: "Widget Service", }) @useAuth(OAuth2Auth<[{ @@ -196,7 +196,7 @@ describe("isOnClient", () => { describe("isCredential", () => { it("apikey", async () => { const { DemoService } = (await runner.compile(` - @service({ + @service(#{ title: "Widget Service", }) @useAuth(ApiKeyAuth) @@ -214,7 +214,7 @@ describe("isCredential", () => { }); it("bearer", async () => { const { DemoService } = (await runner.compile(` - @service({ + @service(#{ title: "Widget Service", }) @useAuth(OAuth2Auth<[{ diff --git a/packages/http-server-csharp/test/test-host.ts b/packages/http-server-csharp/test/test-host.ts index 9fee46b7ca5..20a17a70e72 100644 --- a/packages/http-server-csharp/test/test-host.ts +++ b/packages/http-server-csharp/test/test-host.ts @@ -38,7 +38,7 @@ export async function createCSharpServiceEmitterTestRunner( export function getStandardService(code: string): string { return ` - @service({title: "Microsoft.Contoso"}) + @service(#{title: "Microsoft.Contoso"}) namespace Microsoft.Contoso { ${code} }`; diff --git a/packages/http-specs/specs/server/endpoint/not-defined/main.tsp b/packages/http-specs/specs/server/endpoint/not-defined/main.tsp index 04962911dce..d477ddb8130 100644 --- a/packages/http-specs/specs/server/endpoint/not-defined/main.tsp +++ b/packages/http-specs/specs/server/endpoint/not-defined/main.tsp @@ -8,9 +8,7 @@ using Spector; * Illustrates server doesn't define endpoint. Client should automatically add an endpoint to let user pass in. */ @route("/server/endpoint/not-defined") -@service({ - title: "Testserver without any endpoint", -}) +@service(#{ title: "Testserver without any endpoint" }) namespace Server.Endpoint.NotDefined; @scenario diff --git a/packages/http-specs/specs/server/path/multiple/main.tsp b/packages/http-specs/specs/server/path/multiple/main.tsp index 868684aeb39..58651bbbea6 100644 --- a/packages/http-specs/specs/server/path/multiple/main.tsp +++ b/packages/http-specs/specs/server/path/multiple/main.tsp @@ -8,9 +8,7 @@ using TypeSpec.Versioning; using TypeSpec.Rest; @versioned(Versions) -@service({ - title: "ServerPathMultiple", -}) +@service(#{ title: "ServerPathMultiple" }) @server( "{endpoint}/server/path/multiple/{apiVersion}", "Test server with path parameters.", diff --git a/packages/http/test/routes.test.ts b/packages/http/test/routes.test.ts index 060d637f85a..08ca205496c 100644 --- a/packages/http/test/routes.test.ts +++ b/packages/http/test/routes.test.ts @@ -79,7 +79,7 @@ describe("http: routes", () => { it("operation in the service namespace are included", async () => { const routes = await getOperations( ` - @service({title: "My Service"}) + @service(#{title: "My Service"}) namespace MyService; @get op index(): void; `, @@ -94,7 +94,7 @@ describe("http: routes", () => { @route("/not-included") @get op notIncluded(): void; - @service({title: "My Service"}) + @service(#{title: "My Service"}) namespace MyService { @route("/included") @get op included(): void; @@ -107,7 +107,7 @@ describe("http: routes", () => { it("interface in the service namespace are included", async () => { const routes = await getOperations( ` - @service({title: "My Service"}) + @service(#{title: "My Service"}) namespace MyService; interface Foo { @get index(): void; @@ -120,7 +120,7 @@ describe("http: routes", () => { it("operation in namespace in the service namespace are be included", async () => { const routes = await getOperations( ` - @service({title: "My Service"}) + @service(#{title: "My Service"}) namespace MyService; namespace MyArea{ @@ -135,7 +135,7 @@ describe("http: routes", () => { it("operation in a different namespace are not included", async () => { const routes = await getOperations( ` - @service({title: "My Service"}) + @service(#{title: "My Service"}) namespace MyService { @route("/included") @get op test(): string; diff --git a/packages/http/test/test-host.ts b/packages/http/test/test-host.ts index e3306f1eefa..8c7748e457d 100644 --- a/packages/http/test/test-host.ts +++ b/packages/http/test/test-host.ts @@ -95,7 +95,7 @@ export async function getOperationsWithServiceNamespace( ): Promise<[HttpOperation[], readonly Diagnostic[]]> { const runner = await createHttpTestRunner(); await runner.compileAndDiagnose( - `@service({title: "Test Service"}) namespace TestService; + `@service(#{title: "Test Service"}) namespace TestService; ${code}`, { noEmit: true, diff --git a/packages/openapi/README.md b/packages/openapi/README.md index b5877f8fa5c..a7108ed9783 100644 --- a/packages/openapi/README.md +++ b/packages/openapi/README.md @@ -107,7 +107,7 @@ Specify OpenAPI additional information. The service `title` and `version` are already specified using `@service`. ```typespec -@TypeSpec.OpenAPI.info(additionalInfo: TypeSpec.OpenAPI.AdditionalInfo) +@TypeSpec.OpenAPI.info(additionalInfo: valueof TypeSpec.OpenAPI.AdditionalInfo) ``` ##### Target @@ -116,9 +116,9 @@ The service `title` and `version` are already specified using `@service`. ##### Parameters -| Name | Type | Description | -| -------------- | ----------------------------------- | ---------------------- | -| additionalInfo | [`AdditionalInfo`](#additionalinfo) | Additional information | +| Name | Type | Description | +| -------------- | ------------------------------------------- | ---------------------- | +| additionalInfo | [valueof `AdditionalInfo`](#additionalinfo) | Additional information | #### `@operationId` diff --git a/packages/openapi/generated-defs/TypeSpec.OpenAPI.ts b/packages/openapi/generated-defs/TypeSpec.OpenAPI.ts index efc7026500b..f5555dd62e1 100644 --- a/packages/openapi/generated-defs/TypeSpec.OpenAPI.ts +++ b/packages/openapi/generated-defs/TypeSpec.OpenAPI.ts @@ -1,11 +1,34 @@ import type { DecoratorContext, Model, Namespace, Operation, Type } from "@typespec/compiler"; +export interface AdditionalInfo { + readonly [key: string]: unknown; + readonly title?: string; + readonly summary?: string; + readonly version?: string; + readonly termsOfService?: string; + readonly contact?: Contact; + readonly license?: License; +} + export interface TagMetadata { readonly [key: string]: unknown; readonly description?: string; readonly externalDocs?: ExternalDocs; } +export interface Contact { + readonly [key: string]: unknown; + readonly name?: string; + readonly url?: string; + readonly email?: string; +} + +export interface License { + readonly [key: string]: unknown; + readonly name: string; + readonly url?: string; +} + export interface ExternalDocs { readonly [key: string]: unknown; readonly url: string; @@ -88,7 +111,7 @@ export type ExternalDocsDecorator = ( export type InfoDecorator = ( context: DecoratorContext, target: Namespace, - additionalInfo: Type, + additionalInfo: AdditionalInfo, ) => void; /** diff --git a/packages/openapi/lib/decorators.tsp b/packages/openapi/lib/decorators.tsp index a5fd3472543..fe5a9d0d21b 100644 --- a/packages/openapi/lib/decorators.tsp +++ b/packages/openapi/lib/decorators.tsp @@ -80,6 +80,8 @@ model AdditionalInfo { /** The license information for the exposed API. */ license?: License; + + ...Record; } /** Contact information for the exposed API. */ @@ -92,6 +94,8 @@ model Contact { /** The email address of the contact person/organization. MUST be in the format of an email address. */ email?: string; + + ...Record; } /** License information for the exposed API. */ @@ -101,6 +105,8 @@ model License { /** A URL to the license used for the API. MUST be in the format of a URL. */ url?: url; + + ...Record; } /** @@ -108,7 +114,7 @@ model License { * The service `title` and `version` are already specified using `@service`. * @param additionalInfo Additional information */ -extern dec info(target: Namespace, additionalInfo: AdditionalInfo); +extern dec info(target: Namespace, additionalInfo: valueof AdditionalInfo); /** Metadata to a single tag that is used by operations. */ model TagMetadata { diff --git a/packages/openapi/src/decorators.ts b/packages/openapi/src/decorators.ts index cf119bd0a73..09497dc9655 100644 --- a/packages/openapi/src/decorators.ts +++ b/packages/openapi/src/decorators.ts @@ -11,7 +11,6 @@ import { Program, Type, typespecTypeToJson, - TypeSpecValue, } from "@typespec/compiler"; import { useStateMap } from "@typespec/compiler/utils"; import { setStatusCode } from "@typespec/http"; @@ -169,13 +168,8 @@ const infoKey = createStateSymbol("info"); export const $info: InfoDecorator = ( context: DecoratorContext, entity: Namespace, - model: TypeSpecValue, + data: AdditionalInfo & Record, ) => { - const [data, diagnostics] = typespecTypeToJson>( - model, - context.getArgumentTarget(0)!, - ); - context.program.reportDiagnostics(diagnostics); if (data === undefined) { return; } diff --git a/packages/openapi/test/decorators.test.ts b/packages/openapi/test/decorators.test.ts index 83480dc1916..6b610347f29 100644 --- a/packages/openapi/test/decorators.test.ts +++ b/packages/openapi/test/decorators.test.ts @@ -194,10 +194,10 @@ describe("openapi: decorators", () => { describe("@info", () => { describe("emit diagnostics when passing extension key not starting with `x-` in additionalInfo", () => { it.each([ - ["root", `{ foo:"Bar" }`], - ["license", `{ license:{ name: "Apache 2.0", foo:"Bar"} }`], - ["contact", `{ contact:{ foo:"Bar"} }`], - ["complex", `{ contact:{ "x-custom": "string" }, foo:"Bar" }`], + ["root", `#{ foo: "Bar" }`], + ["license", `#{ license: #{ name: "Apache 2.0", foo:"Bar"} }`], + ["contact", `#{ contact: #{ foo:"Bar"} }`], + ["complex", `#{ contact: #{ \`x-custom\`: "string" }, foo:"Bar" }`], ])("%s", async (_, code) => { const diagnostics = await runner.diagnose(` @info(${code}) @@ -212,9 +212,9 @@ describe("openapi: decorators", () => { it("multiple", async () => { const diagnostics = await runner.diagnose(` - @info({ - license:{ name: "Apache 2.0", foo1:"Bar"}, - contact:{ "x-custom": "string", foo2:"Bar" }, + @info(#{ + license: #{ name: "Apache 2.0", foo1:"Bar"}, + contact: #{ \`x-custom\`: "string", foo2:"Bar" }, foo3:"Bar" }) @test namespace Service; @@ -239,7 +239,7 @@ describe("openapi: decorators", () => { it("emit diagnostic if termsOfService is not a valid url", async () => { const diagnostics = await runner.diagnose(` - @info({termsOfService:"notvalidurl"}) + @info(#{termsOfService:"notvalidurl"}) @test namespace Service {} `); @@ -251,7 +251,7 @@ describe("openapi: decorators", () => { it("emit diagnostic if use on non namespace", async () => { const diagnostics = await runner.diagnose(` - @info({}) + @info(#{}) model Foo {} `); @@ -274,17 +274,17 @@ describe("openapi: decorators", () => { it("set all properties", async () => { const { Service } = (await runner.compile(` - @info({ + @info(#{ title: "My API", version: "1.0.0", summary: "My API summary", termsOfService: "http://example.com/terms/", - contact: { + contact: #{ name: "API Support", url: "http://www.example.com/support", email: "support@example.com" }, - license: { + license: #{ name: "Apache 2.0", url: "http://www.apache.org/licenses/LICENSE-2.0.html" }, @@ -311,14 +311,13 @@ describe("openapi: decorators", () => { it("resolveInfo() merge with data from @service and @summary", async () => { const { Service } = (await runner.compile(` - @service({ + #suppress "deprecated" "Test" + @service(#{ title: "Service API", - - #suppress "deprecated" "Test" version: "2.0.0" }) @summary("My summary") - @info({ + @info(#{ version: "1.0.0", termsOfService: "http://example.com/terms/", }) diff --git a/packages/openapi/test/helpers.test.ts b/packages/openapi/test/helpers.test.ts index 019f0e55902..4328ba0eeb5 100644 --- a/packages/openapi/test/helpers.test.ts +++ b/packages/openapi/test/helpers.test.ts @@ -23,7 +23,7 @@ describe("openapi: helpers", () => { it("return operation name if operation is defined under service namespace", async () => { const id = await testResolveOperationId(` - @service({title: "Abc"}) + @service(#{title: "Abc"}) namespace MyService; @test op foo(): string; @@ -42,7 +42,7 @@ describe("openapi: helpers", () => { it("return group name and operation name if operation is defined under namespace that is not the service namespace", async () => { const id = await testResolveOperationId(` - @service({title: "Abc"}) + @service(#{title: "Abc"}) namespace MyService; namespace Bar { diff --git a/packages/openapi3/src/cli/actions/convert/generators/generate-service-info.ts b/packages/openapi3/src/cli/actions/convert/generators/generate-service-info.ts index 1abd57ce877..c749b856a97 100644 --- a/packages/openapi3/src/cli/actions/convert/generators/generate-service-info.ts +++ b/packages/openapi3/src/cli/actions/convert/generators/generate-service-info.ts @@ -1,6 +1,7 @@ import { TypeSpecServiceInfo } from "../interfaces.js"; import { generateDocs } from "../utils/docs.js"; import { generateNamespaceName } from "../utils/generate-namespace-name.js"; +import { toTspValues } from "../utils/tsp-values.js"; export function generateServiceInformation(serviceInfo: TypeSpecServiceInfo): string { const definitions: string[] = []; @@ -8,10 +9,10 @@ export function generateServiceInformation(serviceInfo: TypeSpecServiceInfo): st const { name, doc, ...info } = serviceInfo; definitions.push(` - @service({ + @service(#{ title: "${name}" }) - @info(${JSON.stringify(info)}) + @info(${toTspValues(info)}) `); if (doc) { diff --git a/packages/openapi3/src/cli/actions/convert/utils/tsp-values.ts b/packages/openapi3/src/cli/actions/convert/utils/tsp-values.ts new file mode 100644 index 00000000000..ff7d3762964 --- /dev/null +++ b/packages/openapi3/src/cli/actions/convert/utils/tsp-values.ts @@ -0,0 +1,23 @@ +/** Convert a JS object to a tsp value */ +export function toTspValues(item: unknown): string { + if (typeof item === "object") { + if (Array.isArray(item)) { + return `#[${item.map(toTspValues).join(", ")}]`; + } else { + const content = Object.entries(item!) + .filter(([, value]) => value !== undefined) + .map(([key, value]) => { + if (typeof value === "string") { + return `${key}: "${value}"`; + } + + return `${key}: ${toTspValues(value)}`; + }) + .join(", "); + + return `#{${content}}`; + } + } else { + return JSON.stringify(item); + } +} diff --git a/packages/openapi3/test/info.test.ts b/packages/openapi3/test/info.test.ts index 2f03239a738..36b29348b70 100644 --- a/packages/openapi3/test/info.test.ts +++ b/packages/openapi3/test/info.test.ts @@ -6,7 +6,7 @@ worksFor(["3.0.0", "3.1.0"], ({ openApiFor }) => { it("set the service title with @service", async () => { const res = await openApiFor( ` - @service({title: "My Service"}) + @service(#{title: "My Service"}) namespace Foo { op test(): string; } @@ -18,8 +18,8 @@ worksFor(["3.0.0", "3.1.0"], ({ openApiFor }) => { it("set the service version with @service", async () => { const res = await openApiFor( ` - @service({ - #suppress "deprecated" "For test" + #suppress "deprecated" "For test" + @service(#{ version: "1.2.3-test" }) namespace Foo { @@ -34,7 +34,7 @@ worksFor(["3.0.0", "3.1.0"], ({ openApiFor }) => { const res = await openApiFor( ` @doc("My service description") - @service({title: "My Service"}) + @service(#{title: "My Service"}) namespace Foo { op test(): string; } @@ -46,7 +46,7 @@ worksFor(["3.0.0", "3.1.0"], ({ openApiFor }) => { const res = await openApiFor( ` @externalDocs("https://example.com", "more info") - @service({title: "My Service"}) + @service(#{title: "My Service"}) namespace Foo { op test(): string; } @@ -62,14 +62,14 @@ worksFor(["3.0.0", "3.1.0"], ({ openApiFor }) => { const res = await openApiFor( ` @service - @info({ + @info(#{ termsOfService: "http://example.com/terms/", - contact: { + contact: #{ name: "API Support", url: "http://www.example.com/support", email: "support@example.com" }, - license: { + license: #{ name: "Apache 2.0", url: "http://www.apache.org/licenses/LICENSE-2.0.html" }, diff --git a/packages/openapi3/test/return-types.test.ts b/packages/openapi3/test/return-types.test.ts index 533e099e088..7e4c958a929 100644 --- a/packages/openapi3/test/return-types.test.ts +++ b/packages/openapi3/test/return-types.test.ts @@ -41,7 +41,7 @@ worksFor(["3.0.0", "3.1.0"], ({ checkFor, openApiFor, objectSchemaIndexer }) => it("defines responses with status codes", async () => { const res = await openApiFor( ` - @service({ name:"Test" }) + @service namespace Test { model CreatedResponse { @statusCode code: "201"; @@ -60,7 +60,7 @@ worksFor(["3.0.0", "3.1.0"], ({ checkFor, openApiFor, objectSchemaIndexer }) => it("defines responses with numeric status codes", async () => { const res = await openApiFor( ` - @service({ name:"Test" }) + @service namespace Test { model CreatedResponse { @statusCode code: 201; @@ -96,7 +96,7 @@ worksFor(["3.0.0", "3.1.0"], ({ checkFor, openApiFor, objectSchemaIndexer }) => it("defines responses with headers and status codes", async () => { const res = await openApiFor( ` - @service({ name:"Test" }) + @service namespace Test { model ETagHeader { @header eTag: string; @@ -143,7 +143,7 @@ worksFor(["3.0.0", "3.1.0"], ({ checkFor, openApiFor, objectSchemaIndexer }) => it("defines responses with headers and status codes in base model", async () => { const res = await openApiFor( ` - @service({ name:"Test" }) + @service namespace Test { model CreatedResponse { @statusCode code: "201"; diff --git a/packages/openapi3/test/servers.test.ts b/packages/openapi3/test/servers.test.ts index cdab3fde4f8..3b6ebb7d8f2 100644 --- a/packages/openapi3/test/servers.test.ts +++ b/packages/openapi3/test/servers.test.ts @@ -7,7 +7,7 @@ worksFor(["3.0.0", "3.1.0"], ({ diagnoseOpenApiFor, openApiFor }) => { it("set a basic server(url)", async () => { const res = await openApiFor( ` - @service({title: "My service"}) + @service(#{title: "My service"}) @server("https://example.com") namespace MyService {} `, @@ -23,7 +23,7 @@ worksFor(["3.0.0", "3.1.0"], ({ diagnoseOpenApiFor, openApiFor }) => { it("set a basic server(url and desc)", async () => { const res = await openApiFor( ` - @service({title: "My service"}) + @service(#{title: "My service"}) @server("https://example.com", "Main server") namespace MyService {} `, @@ -40,7 +40,7 @@ worksFor(["3.0.0", "3.1.0"], ({ diagnoseOpenApiFor, openApiFor }) => { it("emit diagnostic when parameter is not a string", async () => { const diagnostics = await diagnoseOpenApiFor( ` - @service({title: "My service"}) + @service(#{title: "My service"}) @server("https://{region}.example.com", "Regional account endpoint", {region: int32}) namespace MyService {} `, @@ -55,7 +55,7 @@ worksFor(["3.0.0", "3.1.0"], ({ diagnoseOpenApiFor, openApiFor }) => { it("emit diagnostic when parameter is an enum of different types", async () => { const diagnostics = await diagnoseOpenApiFor( ` - @service({title: "My service"}) + @service(#{title: "My service"}) @server("https://{region}.example.com", "Regional account endpoint", {region: Region}) namespace MyService {} @@ -75,7 +75,7 @@ worksFor(["3.0.0", "3.1.0"], ({ diagnoseOpenApiFor, openApiFor }) => { it("emit diagnostic when parameter is a union of non string types", async () => { const diagnostics = await diagnoseOpenApiFor( ` - @service({title: "My service"}) + @service(#{title: "My service"}) @server("https://{region}.example.com", "Regional account endpoint", {region: string | int32}) namespace MyService {} `, @@ -90,7 +90,7 @@ worksFor(["3.0.0", "3.1.0"], ({ diagnoseOpenApiFor, openApiFor }) => { it("set a server with parameters", async () => { const res = await openApiFor( ` - @service({title: "My service"}) + @service(#{title: "My service"}) @server("https://{account}.{region}.example.com", "Regional account endpoint", {region: string, account: string}) namespace MyService {} `, @@ -110,7 +110,7 @@ worksFor(["3.0.0", "3.1.0"], ({ diagnoseOpenApiFor, openApiFor }) => { it("set a server with parameters with defaults", async () => { const res = await openApiFor( ` - @service({title: "My service"}) + @service(#{title: "My service"}) @server("https://{account}.{region}.example.com", "Regional account endpoint", { region?: string = "westus", account?: string = "default", @@ -133,7 +133,7 @@ worksFor(["3.0.0", "3.1.0"], ({ diagnoseOpenApiFor, openApiFor }) => { it("set a server with parameters with doc", async () => { const res = await openApiFor( ` - @service({title: "My service"}) + @service(#{title: "My service"}) @server("https://{region}.example.com", "Regional account endpoint", { @doc("Region name") region: string, @@ -155,7 +155,7 @@ worksFor(["3.0.0", "3.1.0"], ({ diagnoseOpenApiFor, openApiFor }) => { it("set a server with parameters with extensions", async () => { const res = await openApiFor( ` - @service({title: "My service"}) + @service(#{title: "My service"}) @server("https://{region}.example.com", "Regional account endpoint", { @extension("x-custom", "Foo") region: string, @@ -178,7 +178,7 @@ worksFor(["3.0.0", "3.1.0"], ({ diagnoseOpenApiFor, openApiFor }) => { const res = await openApiFor( ` enum Region { westus, eastus } - @service({title: "My service"}) + @service(#{title: "My service"}) @server("https://{region}.example.com", "Regional account endpoint", { region: Region, }) @@ -200,7 +200,7 @@ worksFor(["3.0.0", "3.1.0"], ({ diagnoseOpenApiFor, openApiFor }) => { const res = await openApiFor( ` enum Region { } - @service({title: "My service"}) + @service(#{title: "My service"}) @server("https://{region}.example.com", "Regional account endpoint", { region: "westus", }) @@ -222,7 +222,7 @@ worksFor(["3.0.0", "3.1.0"], ({ diagnoseOpenApiFor, openApiFor }) => { const res = await openApiFor( ` enum Region { } - @service({title: "My service"}) + @service(#{title: "My service"}) @server("https://{region}.example.com", "Regional account endpoint", { region: "westus" | "eastus", }) diff --git a/packages/openapi3/test/shared-routes.test.ts b/packages/openapi3/test/shared-routes.test.ts index 4d6d18b7f3d..41821c6a933 100644 --- a/packages/openapi3/test/shared-routes.test.ts +++ b/packages/openapi3/test/shared-routes.test.ts @@ -7,7 +7,7 @@ worksFor(["3.0.0", "3.1.0"], ({ diagnoseOpenApiFor, openApiFor }) => { it("emits warning for routes containing query parameters", async () => { const diagnostics = await diagnoseOpenApiFor( ` - @service({title: "My Service"}) + @service(#{title: "My Service"}) namespace Foo { model Resource { id: string; @@ -36,7 +36,7 @@ worksFor(["3.0.0", "3.1.0"], ({ diagnoseOpenApiFor, openApiFor }) => { it("model shared routes that differ by query params as a union of optional params", async () => { const results = await openApiFor( ` - @service({title: "My Service"}) + @service(#{title: "My Service"}) namespace Foo { model Resource { id: string; @@ -100,7 +100,7 @@ worksFor(["3.0.0", "3.1.0"], ({ diagnoseOpenApiFor, openApiFor }) => { it("model shared routes that differ by query param values as an enum", async () => { const results = await openApiFor( ` - @service({title: "My Service"}) + @service(#{title: "My Service"}) namespace Foo { model Resource { id: string; @@ -146,7 +146,7 @@ worksFor(["3.0.0", "3.1.0"], ({ diagnoseOpenApiFor, openApiFor }) => { it("model shared routes with shared parameters in different locations", async () => { const results = await openApiFor( ` - @service({title: "My Service"}) + @service(#{title: "My Service"}) namespace Foo { model Resource { id: string; @@ -201,7 +201,7 @@ worksFor(["3.0.0", "3.1.0"], ({ diagnoseOpenApiFor, openApiFor }) => { it("model shared routes with different response types", async () => { const results = await openApiFor( ` - @service({title: "My Service"}) + @service(#{title: "My Service"}) namespace Foo { model Resource { id: string; @@ -247,7 +247,7 @@ worksFor(["3.0.0", "3.1.0"], ({ diagnoseOpenApiFor, openApiFor }) => { it("model shared routes with different request bodies", async () => { const results = await openApiFor( ` - @service({title: "My Service"}) + @service(#{title: "My Service"}) namespace Foo { @sharedRoute @route("/1") @@ -310,7 +310,7 @@ worksFor(["3.0.0", "3.1.0"], ({ diagnoseOpenApiFor, openApiFor }) => { it("model shared routes with different response bodies", async () => { const results = await openApiFor( ` - @service({title: "My Service"}) + @service(#{title: "My Service"}) namespace Foo { model A { @@ -363,7 +363,7 @@ worksFor(["3.0.0", "3.1.0"], ({ diagnoseOpenApiFor, openApiFor }) => { it("model shared routes with different implicit request bodies", async () => { const results = await openApiFor( ` - @service({title: "My Service"}) + @service(#{title: "My Service"}) namespace Foo { model A { name: string; @@ -420,7 +420,7 @@ worksFor(["3.0.0", "3.1.0"], ({ diagnoseOpenApiFor, openApiFor }) => { it("model shared routes with different request and response body types", async () => { const results = await openApiFor( ` - @service({title: "My Service"}) + @service(#{title: "My Service"}) namespace Foo { @error @@ -504,7 +504,7 @@ worksFor(["3.0.0", "3.1.0"], ({ diagnoseOpenApiFor, openApiFor }) => { it("should warn if shared routes differ by `@parameterVisibility`", async () => { const diagnostics = await diagnoseOpenApiFor( ` - @service({title: "My Service"}) + @service(#{title: "My Service"}) namespace Foo { model Resource { @visibility(Lifecycle.Read) diff --git a/packages/openapi3/test/test-host.ts b/packages/openapi3/test/test-host.ts index 84b9655b89c..8774cdb40ff 100644 --- a/packages/openapi3/test/test-host.ts +++ b/packages/openapi3/test/test-host.ts @@ -138,7 +138,7 @@ export async function oapiForModel( const oapi = await openApiFor( ` ${modelDef}; - @service({title: "Testing model"}) + @service(#{title: "Testing model"}) @route("/") namespace root { op read(): { @body body: ${name} }; diff --git a/packages/openapi3/test/tsp-openapi3/convert-openapi3-doc.test.ts b/packages/openapi3/test/tsp-openapi3/convert-openapi3-doc.test.ts index 1c4550a2547..1d8389dd43f 100644 --- a/packages/openapi3/test/tsp-openapi3/convert-openapi3-doc.test.ts +++ b/packages/openapi3/test/tsp-openapi3/convert-openapi3-doc.test.ts @@ -31,12 +31,8 @@ it("should convert an OpenAPI3 document to a formatted TypeSpec program", async using Http; using OpenAPI; - @service({ - title: "Test Service", - }) - @info({ - version: "1.0.0", - }) + @service(#{ title: "Test Service" }) + @info(#{ version: "1.0.0" }) namespace TestService; scalar Foo extends string; @@ -72,10 +68,10 @@ it("converts an OpenAPI 3 document with an empty schema to a valid TypeSpec repr using Http; using OpenAPI; - @service({ + @service(#{ title: "Test", }) - @info({ + @info(#{ version: "0.0.0", }) namespace Test; diff --git a/packages/openapi3/test/tsp-openapi3/output/escaped-identifiers/main.tsp b/packages/openapi3/test/tsp-openapi3/output/escaped-identifiers/main.tsp index 4e9be056563..b3e3439bc04 100644 --- a/packages/openapi3/test/tsp-openapi3/output/escaped-identifiers/main.tsp +++ b/packages/openapi3/test/tsp-openapi3/output/escaped-identifiers/main.tsp @@ -5,12 +5,8 @@ import "@typespec/openapi3"; using Http; using OpenAPI; -@service({ - title: "Sample API", -}) -@info({ - version: "1.0.0", -}) +@service(#{ title: "Sample API" }) +@info(#{ version: "1.0.0" }) namespace SampleAPI; scalar `Foo-Bar` extends string; diff --git a/packages/openapi3/test/tsp-openapi3/output/nested/main.tsp b/packages/openapi3/test/tsp-openapi3/output/nested/main.tsp index 02a066370a9..23b8632ae44 100644 --- a/packages/openapi3/test/tsp-openapi3/output/nested/main.tsp +++ b/packages/openapi3/test/tsp-openapi3/output/nested/main.tsp @@ -5,12 +5,8 @@ import "@typespec/openapi3"; using Http; using OpenAPI; -@service({ - title: "Nested sample", -}) -@info({ - version: "0.0.0", -}) +@service(#{ title: "Nested sample" }) +@info(#{ version: "0.0.0" }) namespace Nestedsample; namespace SubA { diff --git a/packages/openapi3/test/tsp-openapi3/output/one-any-all/main.tsp b/packages/openapi3/test/tsp-openapi3/output/one-any-all/main.tsp index f6ef55805a8..f7a9d7dfcbe 100644 --- a/packages/openapi3/test/tsp-openapi3/output/one-any-all/main.tsp +++ b/packages/openapi3/test/tsp-openapi3/output/one-any-all/main.tsp @@ -5,12 +5,8 @@ import "@typespec/openapi3"; using Http; using OpenAPI; -@service({ - title: "OneAnyAll Service", -}) -@info({ - version: "0.0.0", -}) +@service(#{ title: "OneAnyAll Service" }) +@info(#{ version: "0.0.0" }) namespace OneAnyAllService; model Cat { diff --git a/packages/openapi3/test/tsp-openapi3/output/openapi-extensions/main.tsp b/packages/openapi3/test/tsp-openapi3/output/openapi-extensions/main.tsp index 90ca2e2eb5d..bf14a467f2d 100644 --- a/packages/openapi3/test/tsp-openapi3/output/openapi-extensions/main.tsp +++ b/packages/openapi3/test/tsp-openapi3/output/openapi-extensions/main.tsp @@ -5,12 +5,8 @@ import "@typespec/openapi3"; using Http; using OpenAPI; -@service({ - title: "(title)", -}) -@info({ - version: "0.0.0", -}) +@service(#{ title: "(title)" }) +@info(#{ version: "0.0.0" }) namespace title; model Foo { diff --git a/packages/openapi3/test/tsp-openapi3/output/param-decorators/main.tsp b/packages/openapi3/test/tsp-openapi3/output/param-decorators/main.tsp index 1612fc409f2..195e0ed87e4 100644 --- a/packages/openapi3/test/tsp-openapi3/output/param-decorators/main.tsp +++ b/packages/openapi3/test/tsp-openapi3/output/param-decorators/main.tsp @@ -5,12 +5,8 @@ import "@typespec/openapi3"; using Http; using OpenAPI; -@service({ - title: "Parameter Decorators", -}) -@info({ - version: "0.0.0", -}) +@service(#{ title: "Parameter Decorators" }) +@info(#{ version: "0.0.0" }) namespace ParameterDecorators; model Thing { diff --git a/packages/openapi3/test/tsp-openapi3/output/petstore-sample/main.tsp b/packages/openapi3/test/tsp-openapi3/output/petstore-sample/main.tsp index d62028e02f9..ad7edce0b77 100644 --- a/packages/openapi3/test/tsp-openapi3/output/petstore-sample/main.tsp +++ b/packages/openapi3/test/tsp-openapi3/output/petstore-sample/main.tsp @@ -5,15 +5,8 @@ import "@typespec/openapi3"; using Http; using OpenAPI; -@service({ - title: "Swagger Petstore", -}) -@info({ - version: "1.0.0", - license: { - name: "MIT", - }, -}) +@service(#{ title: "Swagger Petstore" }) +@info(#{ version: "1.0.0", license: #{ name: "MIT" } }) namespace SwaggerPetstore; model Pet { diff --git a/packages/openapi3/test/tsp-openapi3/output/petstore-swagger/main.tsp b/packages/openapi3/test/tsp-openapi3/output/petstore-swagger/main.tsp index 564d2e7f412..5269e2d43b5 100644 --- a/packages/openapi3/test/tsp-openapi3/output/petstore-swagger/main.tsp +++ b/packages/openapi3/test/tsp-openapi3/output/petstore-swagger/main.tsp @@ -15,18 +15,11 @@ using OpenAPI; * - [The Pet Store repository](https://github.com/swagger-api/swagger-petstore) * - [The source API definition for the Pet Store](https://github.com/swagger-api/swagger-petstore/blob/master/src/main/resources/openapi.yaml) */ -@service({ - title: "Swagger Petstore - OpenAPI 3.0", -}) -@info({ +@service(#{ title: "Swagger Petstore - OpenAPI 3.0" }) +@info(#{ version: "1.0.20-SNAPSHOT", - contact: { - email: "apiteam@swagger.io", - }, - license: { - name: "Apache 2.0", - url: "http://www.apache.org/licenses/LICENSE-2.0.html", - }, + contact: #{ email: "apiteam@swagger.io" }, + license: #{ name: "Apache 2.0", url: "http://www.apache.org/licenses/LICENSE-2.0.html" }, termsOfService: "http://swagger.io/terms/", }) namespace SwaggerPetstoreOpenAPI30; diff --git a/packages/openapi3/test/tsp-openapi3/output/playground-http-service/main.tsp b/packages/openapi3/test/tsp-openapi3/output/playground-http-service/main.tsp index 13ca1e5b3dc..377e200b391 100644 --- a/packages/openapi3/test/tsp-openapi3/output/playground-http-service/main.tsp +++ b/packages/openapi3/test/tsp-openapi3/output/playground-http-service/main.tsp @@ -5,12 +5,8 @@ import "@typespec/openapi3"; using Http; using OpenAPI; -@service({ - title: "Widget Service", -}) -@info({ - version: "0.0.0", -}) +@service(#{ title: "Widget Service" }) +@info(#{ version: "0.0.0" }) namespace WidgetService; model Error { diff --git a/packages/openapi3/test/tsp-openapi3/output/polymorphism/main.tsp b/packages/openapi3/test/tsp-openapi3/output/polymorphism/main.tsp index 08cf3b5ee42..cd7d72efbd9 100644 --- a/packages/openapi3/test/tsp-openapi3/output/polymorphism/main.tsp +++ b/packages/openapi3/test/tsp-openapi3/output/polymorphism/main.tsp @@ -5,12 +5,8 @@ import "@typespec/openapi3"; using Http; using OpenAPI; -@service({ - title: "Polymorphism sample", -}) -@info({ - version: "0.0.0", -}) +@service(#{ title: "Polymorphism sample" }) +@info(#{ version: "0.0.0" }) namespace Polymorphismsample; model Cat extends Pet { diff --git a/packages/openapi3/test/tsp-openapi3/output/status-code-changes/main.tsp b/packages/openapi3/test/tsp-openapi3/output/status-code-changes/main.tsp index 8c12c552f99..f65d6f1e16b 100644 --- a/packages/openapi3/test/tsp-openapi3/output/status-code-changes/main.tsp +++ b/packages/openapi3/test/tsp-openapi3/output/status-code-changes/main.tsp @@ -5,12 +5,8 @@ import "@typespec/openapi3"; using Http; using OpenAPI; -@service({ - title: "(title)", -}) -@info({ - version: "0.0.0", -}) +@service(#{ title: "(title)" }) +@info(#{ version: "0.0.0" }) namespace title; model Pet { diff --git a/packages/openapi3/test/tsp-openapi3/parameters.test.ts b/packages/openapi3/test/tsp-openapi3/parameters.test.ts index 0c7ace2ab43..495f80f2e95 100644 --- a/packages/openapi3/test/tsp-openapi3/parameters.test.ts +++ b/packages/openapi3/test/tsp-openapi3/parameters.test.ts @@ -342,12 +342,8 @@ describe("header", () => { using Http; using OpenAPI; - @service({ - title: "Test Service", - }) - @info({ - version: "1.0.0", - }) + @service(#{ title: "Test Service" }) + @info(#{ version: "1.0.0" }) namespace TestService; @route("/") @get op foo( @@ -394,12 +390,8 @@ describe("header", () => { using Http; using OpenAPI; - @service({ - title: "Test Service", - }) - @info({ - version: "1.0.0", - }) + @service(#{ title: "Test Service" }) + @info(#{ version: "1.0.0" }) namespace TestService; @route("/") @get op foo( diff --git a/packages/openapi3/test/tsp-openapi3/paths.test.ts b/packages/openapi3/test/tsp-openapi3/paths.test.ts index a31422a1d5b..2ef9c4acacc 100644 --- a/packages/openapi3/test/tsp-openapi3/paths.test.ts +++ b/packages/openapi3/test/tsp-openapi3/paths.test.ts @@ -39,12 +39,8 @@ it("generates operations with no params", async () => { using Http; using OpenAPI; - @service({ - title: "Test Service", - }) - @info({ - version: "1.0.0", - }) + @service(#{ title: "Test Service" }) + @info(#{ version: "1.0.0" }) namespace TestService; @route("/") @get op rootGet(): Body<{ @@ -79,12 +75,8 @@ it("generates operations without common params", async () => { using Http; using OpenAPI; - @service({ - title: "Test Service", - }) - @info({ - version: "1.0.0", - }) + @service(#{ title: "Test Service" }) + @info(#{ version: "1.0.0" }) namespace TestService; @route("/{id}") @get op idGet(@path id: string): Body<{ @@ -120,12 +112,8 @@ it("generates operations with common params", async () => { using Http; using OpenAPI; - @service({ - title: "Test Service", - }) - @info({ - version: "1.0.0", - }) + @service(#{ title: "Test Service" }) + @info(#{ version: "1.0.0" }) namespace TestService; @route("/{id}") @get op idGet(@path id: string): Body<{ @@ -161,12 +149,8 @@ it("generates operations with common and specific params", async () => { using Http; using OpenAPI; - @service({ - title: "Test Service", - }) - @info({ - version: "1.0.0", - }) + @service(#{ title: "Test Service" }) + @info(#{ version: "1.0.0" }) namespace TestService; @route("/{id}") @get op idGet(@path id: string, @query(#{ explode: true }) foo?: string): Body<{ @@ -218,12 +202,8 @@ it("supports overriding common params with operation params", async () => { using Http; using OpenAPI; - @service({ - title: "Test Service", - }) - @info({ - version: "1.0.0", - }) + @service(#{ title: "Test Service" }) + @info(#{ version: "1.0.0" }) namespace TestService; @route("/{id}") @get op idGet( @@ -267,12 +247,8 @@ it("supports operation summary", async () => { using Http; using OpenAPI; - @service({ - title: "Test Service", - }) - @info({ - version: "1.0.0", - }) + @service(#{ title: "Test Service" }) + @info(#{ version: "1.0.0" }) namespace TestService; @route("/") @@ -334,12 +310,8 @@ import "@typespec/openapi3"; using Http; using OpenAPI; -@service({ - title: "Test Service", -}) -@info({ - version: "1.0.0", -}) +@service(#{ title: "Test Service" }) +@info(#{ version: "1.0.0" }) namespace TestService; model Foo { @@ -395,12 +367,8 @@ model Foo { using Http; using OpenAPI; - @service({ - title: "Test Service", - }) - @info({ - version: "1.0.0", - }) + @service(#{ title: "Test Service" }) + @info(#{ version: "1.0.0" }) namespace TestService; model Foo { @@ -441,12 +409,8 @@ model Foo { using Http; using OpenAPI; - @service({ - title: "Test Service", - }) - @info({ - version: "1.0.0", - }) + @service(#{ title: "Test Service" }) + @info(#{ version: "1.0.0" }) namespace TestService; @route("/") @get op getFoo(): CreatedResponse & { @@ -485,12 +449,8 @@ model Foo { using Http; using OpenAPI; - @service({ - title: "Test Service", - }) - @info({ - version: "1.0.0", - }) + @service(#{ title: "Test Service" }) + @info(#{ version: "1.0.0" }) namespace TestService; @route("/") @get op getFoo(): { @@ -550,12 +510,8 @@ model Foo { using Http; using OpenAPI; - @service({ - title: "Test Service", - }) - @info({ - version: "1.0.0", - }) + @service(#{ title: "Test Service" }) + @info(#{ version: "1.0.0" }) namespace TestService; model Foo { @@ -607,12 +563,8 @@ model Foo { using Http; using OpenAPI; - @service({ - title: "Test Service", - }) - @info({ - version: "1.0.0", - }) + @service(#{ title: "Test Service" }) + @info(#{ version: "1.0.0" }) namespace TestService; @route("/") @get op getFoo(): Body<{ @@ -651,12 +603,8 @@ model Foo { using Http; using OpenAPI; - @service({ - title: "Test Service", - }) - @info({ - version: "1.0.0", - }) + @service(#{ title: "Test Service" }) + @info(#{ version: "1.0.0" }) namespace TestService; @route("/") @get op getFoo(): { @@ -695,12 +643,8 @@ model Foo { using Http; using OpenAPI; - @service({ - title: "Test Service", - }) - @info({ - version: "1.0.0", - }) + @service(#{ title: "Test Service" }) + @info(#{ version: "1.0.0" }) namespace TestService; @route("/") @get op getFoo(): { @@ -739,12 +683,8 @@ model Foo { using Http; using OpenAPI; - @service({ - title: "Test Service", - }) - @info({ - version: "1.0.0", - }) + @service(#{ title: "Test Service" }) + @info(#{ version: "1.0.0" }) namespace TestService; @route("/") @get op getFoo(): GeneratedHelpers.DefaultResponse; @@ -792,12 +732,8 @@ model Foo { using Http; using OpenAPI; - @service({ - title: "Test Service", - }) - @info({ - version: "1.0.0", - }) + @service(#{ title: "Test Service" }) + @info(#{ version: "1.0.0" }) namespace TestService; @route("/") @get op getFoo(): GeneratedHelpers.DefaultResponse; @@ -845,12 +781,8 @@ model Foo { using Http; using OpenAPI; - @service({ - title: "Test Service", - }) - @info({ - version: "1.0.0", - }) + @service(#{ title: "Test Service" }) + @info(#{ version: "1.0.0" }) namespace TestService; @route("/") @get op getFoo(): GeneratedHelpers.DefaultResponse; @@ -955,12 +883,8 @@ model Foo { using Http; using OpenAPI; - @service({ - title: "Test Service", - }) - @info({ - version: "1.0.0", - }) + @service(#{ title: "Test Service" }) + @info(#{ version: "1.0.0" }) namespace TestService; @route("/") @get op getFoo(): GeneratedHelpers.DefaultResponse< @@ -1031,12 +955,8 @@ model Foo { using Http; using OpenAPI; - @service({ - title: "Test Service", - }) - @info({ - version: "1.0.0", - }) + @service(#{ title: "Test Service" }) + @info(#{ version: "1.0.0" }) namespace TestService; scalar Foo extends string; @@ -1094,12 +1014,8 @@ model Foo { using Http; using OpenAPI; - @service({ - title: "Test Service", - }) - @info({ - version: "1.0.0", - }) + @service(#{ title: "Test Service" }) + @info(#{ version: "1.0.0" }) namespace TestService; @route("/") @get op getFoo(): @@ -1180,12 +1096,8 @@ model Foo { using Http; using OpenAPI; - @service({ - title: "Test Service", - }) - @info({ - version: "1.0.0", - }) + @service(#{ title: "Test Service" }) + @info(#{ version: "1.0.0" }) namespace TestService; model Foo { @@ -1255,12 +1167,8 @@ model Foo { using Http; using OpenAPI; - @service({ - title: "Test Service", - }) - @info({ - version: "1.0.0", - }) + @service(#{ title: "Test Service" }) + @info(#{ version: "1.0.0" }) namespace TestService; model Foo { @@ -1351,12 +1259,8 @@ model Foo { using Http; using OpenAPI; - @service({ - title: "Test Service", - }) - @info({ - version: "1.0.0", - }) + @service(#{ title: "Test Service" }) + @info(#{ version: "1.0.0" }) namespace TestService; model Foo { @@ -1424,12 +1328,8 @@ describe("requestBody", () => { using Http; using OpenAPI; - @service({ - title: "Test Service", - }) - @info({ - version: "1.0.0", - }) + @service(#{ title: "Test Service" }) + @info(#{ version: "1.0.0" }) namespace TestService; model Foo { @@ -1497,12 +1397,8 @@ describe("requestBody", () => { using Http; using OpenAPI; - @service({ - title: "Test Service", - }) - @info({ - version: "1.0.0", - }) + @service(#{ title: "Test Service" }) + @info(#{ version: "1.0.0" }) namespace TestService; model Foo { @@ -1571,12 +1467,8 @@ describe("requestBody", () => { using Http; using OpenAPI; - @service({ - title: "Test Service", - }) - @info({ - version: "1.0.0", - }) + @service(#{ title: "Test Service" }) + @info(#{ version: "1.0.0" }) namespace TestService; model Foo { diff --git a/packages/openapi3/test/versioning.test.ts b/packages/openapi3/test/versioning.test.ts index 10b59a3ff07..f29a92e004e 100644 --- a/packages/openapi3/test/versioning.test.ts +++ b/packages/openapi3/test/versioning.test.ts @@ -10,7 +10,7 @@ worksFor(["3.0.0", "3.1.0"], ({ openApiFor, version: specVersion }) => { const { v1, v2, v3 } = await openApiFor( ` @versioned(Versions) - @service({title: "My Service"}) + @service(#{title: "My Service"}) namespace MyService { enum Versions { @useDependency(MyLibrary.Versions.A) @@ -134,7 +134,7 @@ worksFor(["3.0.0", "3.1.0"], ({ openApiFor, version: specVersion }) => { enum Versions { v1 }; } @armNamespace - @service({title: "Widgets 'r' Us"}) + @service(#{title: "Widgets 'r' Us"}) @useDependency(Contoso.Library.Versions.v1) namespace Contoso.WidgetService { model Widget { @@ -169,7 +169,7 @@ worksFor(["3.0.0", "3.1.0"], ({ openApiFor, version: specVersion }) => { } } - @service({title: "Service"}) + @service(#{title: "Service"}) @useDependency(Library.Versions.v1) namespace Service { model Widget { diff --git a/packages/playground-website/samples/http.tsp b/packages/playground-website/samples/http.tsp index d25f354a3ba..c498f301588 100644 --- a/packages/playground-website/samples/http.tsp +++ b/packages/playground-website/samples/http.tsp @@ -1,9 +1,7 @@ import "@typespec/http"; using TypeSpec.Http; -@service({ - title: "Widget Service", -}) +@service(#{ title: "Widget Service" }) namespace DemoService; model Widget { diff --git a/packages/playground-website/samples/rest.tsp b/packages/playground-website/samples/rest.tsp index 0041002cc8c..875408d0bd2 100644 --- a/packages/playground-website/samples/rest.tsp +++ b/packages/playground-website/samples/rest.tsp @@ -1,9 +1,7 @@ import "@typespec/http"; import "@typespec/rest"; -@service({ - title: "Widget Service", -}) +@service(#{ title: "Widget Service" }) namespace DemoService; using TypeSpec.Http; diff --git a/packages/playground-website/samples/unions.tsp b/packages/playground-website/samples/unions.tsp index 187888454b0..809f636bd63 100644 --- a/packages/playground-website/samples/unions.tsp +++ b/packages/playground-website/samples/unions.tsp @@ -2,9 +2,7 @@ import "@typespec/http"; import "@typespec/rest"; import "@typespec/openapi3"; -@service({ - title: "Widget Service", -}) +@service(#{ title: "Widget Service" }) namespace DemoService; using TypeSpec.Rest; using TypeSpec.Http; diff --git a/packages/playground-website/samples/versioning.tsp b/packages/playground-website/samples/versioning.tsp index 3daded456ff..552249f215f 100644 --- a/packages/playground-website/samples/versioning.tsp +++ b/packages/playground-website/samples/versioning.tsp @@ -5,9 +5,7 @@ import "@typespec/versioning"; using TypeSpec.Versioning; @versioned(Versions) -@service({ - title: "Widget Service", -}) +@service(#{ title: "Widget Service" }) namespace DemoService; enum Versions { diff --git a/packages/rest/test/routes.test.ts b/packages/rest/test/routes.test.ts index 8239d11536f..ee43ebc1530 100644 --- a/packages/rest/test/routes.test.ts +++ b/packages/rest/test/routes.test.ts @@ -196,7 +196,7 @@ describe("rest: routes", () => { op action(): void; } - @service({title: "Test"}) + @service(#{title: "Test"}) namespace Test { op my is Lib.action; @route("my") @@ -218,7 +218,7 @@ describe("rest: routes", () => { } } - @service({title: "Test"}) + @service(#{title: "Test"}) namespace Test { interface Mys extends Lib.Ops { } @@ -241,7 +241,7 @@ describe("rest: routes", () => { } } - @service({title: "Test"}) + @service(#{title: "Test"}) namespace Test { @route("my") interface Mys2 extends Lib.Ops {} @@ -263,7 +263,7 @@ describe("rest: routes", () => { op action(@path @segment("pets") id: string): void; } - @service({title: "Test"}) + @service(#{title: "Test"}) namespace Test { op my is Lib.action; @@ -286,7 +286,7 @@ describe("rest: routes", () => { } } - @service({title: "Test"}) + @service(#{title: "Test"}) namespace Test { interface Mys extends Lib.Ops {} @route("my") @@ -308,7 +308,7 @@ describe("rest: routes", () => { } } - @service({title: "Test"}) + @service(#{title: "Test"}) namespace Test { interface Mys extends Lib.Ops {} @route("my") diff --git a/packages/rest/test/test-host.ts b/packages/rest/test/test-host.ts index 564e0485068..83e81fc2489 100644 --- a/packages/rest/test/test-host.ts +++ b/packages/rest/test/test-host.ts @@ -88,7 +88,7 @@ export async function getOperationsWithServiceNamespace( ): Promise<[HttpOperation[], readonly Diagnostic[]]> { const runner = await createRestTestRunner(); await runner.compileAndDiagnose( - `@service({title: "Test Service"}) namespace TestService; + `@service(#{title: "Test Service"}) namespace TestService; ${code}`, { noEmit: true, diff --git a/packages/samples/specs/authentication/interface-auth.tsp b/packages/samples/specs/authentication/interface-auth.tsp index d0c472b9550..ce96f290e39 100644 --- a/packages/samples/specs/authentication/interface-auth.tsp +++ b/packages/samples/specs/authentication/interface-auth.tsp @@ -2,9 +2,7 @@ import "@typespec/rest"; using TypeSpec.Http; -@service({ - title: "Authenticated service with interface override", -}) +@service(#{ title: "Authenticated service with interface override" }) @useAuth(BearerAuth) namespace TypeSpec.InterfaceAuth; diff --git a/packages/samples/specs/authentication/operation-auth.tsp b/packages/samples/specs/authentication/operation-auth.tsp index 21d7dd448c7..64fa3dbec60 100644 --- a/packages/samples/specs/authentication/operation-auth.tsp +++ b/packages/samples/specs/authentication/operation-auth.tsp @@ -2,9 +2,7 @@ import "@typespec/rest"; using TypeSpec.Http; -@service({ - title: "Authenticated service with method override", -}) +@service(#{ title: "Authenticated service with method override" }) @useAuth(BearerAuth | MyAuth<["read", "write"]>) namespace TypeSpec.OperationAuth; diff --git a/packages/samples/specs/authentication/service-auth.tsp b/packages/samples/specs/authentication/service-auth.tsp index acb28e4203a..8abd01d102e 100644 --- a/packages/samples/specs/authentication/service-auth.tsp +++ b/packages/samples/specs/authentication/service-auth.tsp @@ -2,9 +2,7 @@ import "@typespec/rest"; using TypeSpec.Http; -@service({ - title: "Authenticated service", -}) +@service(#{ title: "Authenticated service" }) @useAuth( // Here authentication can either be a // - ApiKey AND Basic Auth together diff --git a/packages/samples/specs/binary/binary.tsp b/packages/samples/specs/binary/binary.tsp index cf830292285..45eb83d5137 100644 --- a/packages/samples/specs/binary/binary.tsp +++ b/packages/samples/specs/binary/binary.tsp @@ -2,9 +2,7 @@ import "@typespec/rest"; using TypeSpec.Http; -@service({ - title: "Binary sample", -}) +@service(#{ title: "Binary sample" }) namespace BinarySample; model HasBytes { diff --git a/packages/samples/specs/documentation/docs.tsp b/packages/samples/specs/documentation/docs.tsp index 5162e4cf704..0189e354425 100644 --- a/packages/samples/specs/documentation/docs.tsp +++ b/packages/samples/specs/documentation/docs.tsp @@ -2,9 +2,7 @@ import "@typespec/rest"; using TypeSpec.Http; -@service({ - title: "Documentation sample", -}) +@service(#{ title: "Documentation sample" }) namespace DocSample; @route("/foo") diff --git a/packages/samples/specs/encoded-names/encoded-names.tsp b/packages/samples/specs/encoded-names/encoded-names.tsp index b09ff7dd13e..802269b35b9 100644 --- a/packages/samples/specs/encoded-names/encoded-names.tsp +++ b/packages/samples/specs/encoded-names/encoded-names.tsp @@ -2,9 +2,7 @@ * This example showcase providing a different name over the wire. * In this example the `WithEncodedNames` model has a `notBefore` property that should get serialized as `nbf` when serialized as json. */ -@service({ - title: "Sample showcasing encoded names", -}) +@service(#{ title: "Sample showcasing encoded names" }) namespace EncodedNames; model WithEncodedNames { diff --git a/packages/samples/specs/grpc-kiosk-example/kiosk.tsp b/packages/samples/specs/grpc-kiosk-example/kiosk.tsp index e6bac422f61..4fdcf101ec4 100644 --- a/packages/samples/specs/grpc-kiosk-example/kiosk.tsp +++ b/packages/samples/specs/grpc-kiosk-example/kiosk.tsp @@ -2,9 +2,7 @@ import "@typespec/rest"; using TypeSpec.Http; -@service({ - title: "Grpc Kiosk sample", -}) +@service(#{ title: "Grpc Kiosk sample" }) namespace GrpcKioskSample; @route("/v1") diff --git a/packages/samples/specs/grpc-library-example/library.tsp b/packages/samples/specs/grpc-library-example/library.tsp index 5e54950f318..275e2d0dcac 100644 --- a/packages/samples/specs/grpc-library-example/library.tsp +++ b/packages/samples/specs/grpc-library-example/library.tsp @@ -8,9 +8,7 @@ import "@typespec/openapi"; using TypeSpec.Http; -@service({ - title: "Grpc Library sample", -}) +@service(#{ title: "Grpc Library sample" }) namespace GrpcLibrarySample; @doc(""" diff --git a/packages/samples/specs/init/main.tsp b/packages/samples/specs/init/main.tsp index 82631cc8903..e8944a33bec 100644 --- a/packages/samples/specs/init/main.tsp +++ b/packages/samples/specs/init/main.tsp @@ -1,9 +1,7 @@ import "@typespec/http"; using TypeSpec.Http; -@service({ - title: "Widget Service", -}) +@service(#{ title: "Widget Service" }) namespace DemoService; model Widget { diff --git a/packages/samples/specs/multiple-types-union/main.tsp b/packages/samples/specs/multiple-types-union/main.tsp index 7c5b72f86f5..041abcf7ca5 100644 --- a/packages/samples/specs/multiple-types-union/main.tsp +++ b/packages/samples/specs/multiple-types-union/main.tsp @@ -1,9 +1,7 @@ import "@typespec/rest"; import "@typespec/openapi"; -@service({ - title: "Pet Store Service", -}) +@service(#{ title: "Pet Store Service" }) namespace PetStore; using TypeSpec.Http; diff --git a/packages/samples/specs/nested/nested.tsp b/packages/samples/specs/nested/nested.tsp index 193a2e8c622..899f96874fe 100644 --- a/packages/samples/specs/nested/nested.tsp +++ b/packages/samples/specs/nested/nested.tsp @@ -2,9 +2,7 @@ import "@typespec/rest"; using TypeSpec.Http; -@service({ - title: "Nested sample", -}) +@service(#{ title: "Nested sample" }) namespace Root { @route("/sub/a") namespace SubA { diff --git a/packages/samples/specs/nullable/nullable.tsp b/packages/samples/specs/nullable/nullable.tsp index 85201bbcddb..a86111b2034 100644 --- a/packages/samples/specs/nullable/nullable.tsp +++ b/packages/samples/specs/nullable/nullable.tsp @@ -3,9 +3,7 @@ import "@typespec/openapi"; using TypeSpec.Http; -@service({ - title: "Nullable sample", -}) +@service(#{ title: "Nullable sample" }) namespace NullableSample; model HasNullables { diff --git a/packages/samples/specs/optional/optional.tsp b/packages/samples/specs/optional/optional.tsp index 583e70de972..c6a0ecc0726 100644 --- a/packages/samples/specs/optional/optional.tsp +++ b/packages/samples/specs/optional/optional.tsp @@ -2,9 +2,7 @@ import "@typespec/rest"; using TypeSpec.Http; -@service({ - title: "Optional sample", -}) +@service(#{ title: "Optional sample" }) namespace OptionalSample; model HasOptional { diff --git a/packages/samples/specs/param-decorators/param-decorators.tsp b/packages/samples/specs/param-decorators/param-decorators.tsp index d9b29b8b149..5de8c5a8d1d 100644 --- a/packages/samples/specs/param-decorators/param-decorators.tsp +++ b/packages/samples/specs/param-decorators/param-decorators.tsp @@ -1,8 +1,6 @@ import "@typespec/rest"; -@service({ - title: "Parameter Decorators", -}) +@service(#{ title: "Parameter Decorators" }) namespace TypeSpec.Samples; using TypeSpec.Http; diff --git a/packages/samples/specs/petstore/petstore.tsp b/packages/samples/specs/petstore/petstore.tsp index 3db18df697b..689bab22228 100644 --- a/packages/samples/specs/petstore/petstore.tsp +++ b/packages/samples/specs/petstore/petstore.tsp @@ -4,9 +4,7 @@ import "./decorators.js"; using TypeSpec.Http; -@service({ - title: "Pet Store Service", -}) +@service(#{ title: "Pet Store Service" }) @doc("This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters.") namespace PetStore; diff --git a/packages/samples/specs/polymorphism/polymorphism.tsp b/packages/samples/specs/polymorphism/polymorphism.tsp index 494bf24852e..94ff4b04716 100644 --- a/packages/samples/specs/polymorphism/polymorphism.tsp +++ b/packages/samples/specs/polymorphism/polymorphism.tsp @@ -3,9 +3,7 @@ import "@typespec/rest"; using TypeSpec.Http; using TypeSpec.Rest; -@service({ - title: "Polymorphism sample", -}) +@service(#{ title: "Polymorphism sample" }) namespace PolymorphismSample; @discriminator("kind") diff --git a/packages/samples/specs/rest-metadata-emitter/main.tsp b/packages/samples/specs/rest-metadata-emitter/main.tsp index c6c928d6a5f..af8db4af6d3 100644 --- a/packages/samples/specs/rest-metadata-emitter/main.tsp +++ b/packages/samples/specs/rest-metadata-emitter/main.tsp @@ -6,9 +6,7 @@ using TypeSpec.Versioning; // Simple services that is versioned and uses metadata and visibility features. @versioned(Versions) -@service({ - title: "User service", -}) +@service(#{ title: "User service" }) namespace UserService { enum Versions { v1, diff --git a/packages/samples/specs/rest/petstore/petstore.tsp b/packages/samples/specs/rest/petstore/petstore.tsp index 8754f966fd5..d96084cffc0 100644 --- a/packages/samples/specs/rest/petstore/petstore.tsp +++ b/packages/samples/specs/rest/petstore/petstore.tsp @@ -1,9 +1,7 @@ import "@typespec/rest"; import "@typespec/openapi"; -@service({ - title: "Pet Store Service", -}) +@service(#{ title: "Pet Store Service" }) namespace PetStore; using TypeSpec.Http; diff --git a/packages/samples/specs/tags/tagged-operations.tsp b/packages/samples/specs/tags/tagged-operations.tsp index 0d960513db6..041b97d0101 100644 --- a/packages/samples/specs/tags/tagged-operations.tsp +++ b/packages/samples/specs/tags/tagged-operations.tsp @@ -2,9 +2,7 @@ import "@typespec/rest"; using TypeSpec.Http; -@service({ - title: "Tags sample", -}) +@service(#{ title: "Tags sample" }) namespace TagsSample; @route("/foo") diff --git a/packages/samples/specs/testserver/body-boolean/body-boolean.tsp b/packages/samples/specs/testserver/body-boolean/body-boolean.tsp index 5a5f809b580..afb4770a065 100644 --- a/packages/samples/specs/testserver/body-boolean/body-boolean.tsp +++ b/packages/samples/specs/testserver/body-boolean/body-boolean.tsp @@ -4,9 +4,7 @@ import "@typespec/openapi"; using TypeSpec.Http; using TypeSpec.OpenAPI; -@service({ - title: "sample", -}) +@service(#{ title: "sample" }) namespace Sample; @doc("Error") diff --git a/packages/samples/specs/testserver/body-complex/body-complex.tsp b/packages/samples/specs/testserver/body-complex/body-complex.tsp index 13b41b3c1e7..e6ba61be194 100644 --- a/packages/samples/specs/testserver/body-complex/body-complex.tsp +++ b/packages/samples/specs/testserver/body-complex/body-complex.tsp @@ -3,9 +3,7 @@ import "@typespec/openapi"; using TypeSpec.Http; -@service({ - title: "sample", -}) +@service(#{ title: "sample" }) namespace Sample; @doc("Error") diff --git a/packages/samples/specs/testserver/body-string/body-string.tsp b/packages/samples/specs/testserver/body-string/body-string.tsp index 60558089b0d..07318b73b76 100644 --- a/packages/samples/specs/testserver/body-string/body-string.tsp +++ b/packages/samples/specs/testserver/body-string/body-string.tsp @@ -4,9 +4,7 @@ import "@typespec/openapi"; using TypeSpec.Http; -@service({ - title: "sample", -}) +@service(#{ title: "sample" }) namespace Sample; @doc("Error") diff --git a/packages/samples/specs/testserver/body-time/body-time.tsp b/packages/samples/specs/testserver/body-time/body-time.tsp index 54ba69bf753..f051fc27bc9 100644 --- a/packages/samples/specs/testserver/body-time/body-time.tsp +++ b/packages/samples/specs/testserver/body-time/body-time.tsp @@ -3,9 +3,7 @@ import "@typespec/openapi"; using TypeSpec.Http; -@service({ - title: "sample", -}) +@service(#{ title: "sample" }) namespace Sample; @doc("Error") diff --git a/packages/samples/specs/testserver/media-types/media-types.tsp b/packages/samples/specs/testserver/media-types/media-types.tsp index 40b9745c950..b1ba9529866 100644 --- a/packages/samples/specs/testserver/media-types/media-types.tsp +++ b/packages/samples/specs/testserver/media-types/media-types.tsp @@ -4,9 +4,7 @@ import "@typespec/openapi"; using TypeSpec.Http; using TypeSpec.OpenAPI; -@service({ - title: "sample", -}) +@service(#{ title: "sample" }) namespace Sample; @doc("Uri or local path to source data.") diff --git a/packages/samples/specs/testserver/multiple-inheritance/multiple-inheritance.tsp b/packages/samples/specs/testserver/multiple-inheritance/multiple-inheritance.tsp index 8efe37d6b8b..fb6080db8d1 100644 --- a/packages/samples/specs/testserver/multiple-inheritance/multiple-inheritance.tsp +++ b/packages/samples/specs/testserver/multiple-inheritance/multiple-inheritance.tsp @@ -3,9 +3,7 @@ import "@typespec/openapi"; using TypeSpec.Http; -@service({ - title: "sample", -}) +@service(#{ title: "sample" }) namespace Sample; model Pet { diff --git a/packages/samples/specs/todoApp/main.tsp b/packages/samples/specs/todoApp/main.tsp index 57cf42dd4cb..cc381efbf9e 100644 --- a/packages/samples/specs/todoApp/main.tsp +++ b/packages/samples/specs/todoApp/main.tsp @@ -6,9 +6,7 @@ import "@typespec/json-schema"; using Http; using JsonSchema; -@service({ - title: "Todo App", -}) +@service(#{ title: "Todo App" }) @useAuth(BearerAuth | ApiKeyAuth) @jsonSchema namespace Todo; diff --git a/packages/samples/specs/use-versioned-lib/main.tsp b/packages/samples/specs/use-versioned-lib/main.tsp index d52b8b38e41..eaeafd498ce 100644 --- a/packages/samples/specs/use-versioned-lib/main.tsp +++ b/packages/samples/specs/use-versioned-lib/main.tsp @@ -5,9 +5,7 @@ import "./library.tsp"; using TypeSpec.Versioning; // Use version 1.0 of the Library -@service({ - title: "Pet Store Service", -}) +@service(#{ title: "Pet Store Service" }) @useDependency(Library.Versions.`1.0`) namespace VersionedApi; using TypeSpec.Http; diff --git a/packages/samples/specs/versioning/main.tsp b/packages/samples/specs/versioning/main.tsp index ffff9cc5d05..d90a81130ef 100644 --- a/packages/samples/specs/versioning/main.tsp +++ b/packages/samples/specs/versioning/main.tsp @@ -5,9 +5,7 @@ import "./library.tsp"; using TypeSpec.Versioning; using TypeSpec.Rest; -@service({ - title: "Pet Store Service", -}) +@service(#{ title: "Pet Store Service" }) @versioned(Versions) namespace VersionedApi; using TypeSpec.Http; diff --git a/packages/samples/specs/visibility/visibility.tsp b/packages/samples/specs/visibility/visibility.tsp index 44c8a8ca72f..27fc205b605 100644 --- a/packages/samples/specs/visibility/visibility.tsp +++ b/packages/samples/specs/visibility/visibility.tsp @@ -4,9 +4,7 @@ import "@typespec/rest"; using TypeSpec.Http; using TypeSpec.Rest; -@service({ - title: "Visibility sample", -}) +@service(#{ title: "Visibility sample" }) namespace VisibilitySample; model Person { diff --git a/packages/versioning/src/lib.ts b/packages/versioning/src/lib.ts index 6183adbefff..271cb8b4fae 100644 --- a/packages/versioning/src/lib.ts +++ b/packages/versioning/src/lib.ts @@ -60,7 +60,7 @@ export const $lib = createTypeSpecLibrary({ "no-service-fixed-version": { severity: "error", messages: { - default: paramMessage`Namespace '${"name"}' cannot specify a fixed service version with @service({version: ${"version"}}) while using @versioned. Remove the version argument from @service.`, + default: paramMessage`Namespace '${"name"}' cannot specify a fixed service version with @service(#{version: ${"version"}}) while using @versioned. Remove the version argument from @service.`, }, }, "incompatible-versioned-reference": { diff --git a/packages/versioning/test/incompatible-versioning.test.ts b/packages/versioning/test/incompatible-versioning.test.ts index d65fd6edda6..9263f573139 100644 --- a/packages/versioning/test/incompatible-versioning.test.ts +++ b/packages/versioning/test/incompatible-versioning.test.ts @@ -25,12 +25,12 @@ describe("versioning: incompatible use of decorators", () => { }); }); - it("emit diagnostic when @service({version: 'X'}) is used with @versioned", async () => { + it("emit diagnostic when @service(#{version: 'X'}) is used with @versioned", async () => { const diagnostics = await runner.diagnose(` + #suppress "deprecated" "For test" @versioned(Versions) - @service({ + @service(#{ title: "Widget Service", - #suppress "deprecated" "For test" version: "v3" }) namespace DemoService; diff --git a/packages/versioning/test/versioned-dependencies.test.ts b/packages/versioning/test/versioned-dependencies.test.ts index e1f6cafd48a..776e1488f73 100644 --- a/packages/versioning/test/versioned-dependencies.test.ts +++ b/packages/versioning/test/versioned-dependencies.test.ts @@ -875,7 +875,7 @@ describe("versioning: dependencies", () => { // Test for https://github.com/microsoft/typespec/issues/760 it("have a nested service namespace", async () => { const { MyService } = (await runner.compile(` - @service({title: "Test"}) + @service(#{title: "Test"}) @useDependency(Lib.Versions.v1) @test("MyService") namespace MyOrg.MyService { @@ -921,7 +921,7 @@ describe("versioning: dependencies", () => { // Test for https://github.com/microsoft/typespec/issues/786 it("have a nested service namespace and libraries sharing common parent namespace", async () => { const { MyService } = (await runner.compile(` - @service({title: "Test"}) + @service(#{title: "Test"}) @useDependency(Lib.One.Versions.v1) @test("MyService") namespace MyOrg.MyService { diff --git a/packages/versioning/test/versioning.test.ts b/packages/versioning/test/versioning.test.ts index 688fd9ffb2d..d18fe4282a9 100644 --- a/packages/versioning/test/versioning.test.ts +++ b/packages/versioning/test/versioning.test.ts @@ -432,7 +432,7 @@ describe("versioning: logic", () => { it("emits diagnostic when renaming causes duplicates", async () => { const code = ` @versioned(Versions) - @service({ + @service(#{ title: "Widget Service", }) namespace DemoService; @@ -968,7 +968,7 @@ describe("versioning: logic", () => { it("emits diagnostic when renaming causes duplicates", async () => { const code = ` @versioned(Versions) - @service({ + @service(#{ title: "Widget Service", }) namespace DemoService; @@ -2046,7 +2046,7 @@ describe("versioning: logic", () => { it("emits diagnostic when renaming causes duplicates", async () => { const code = ` @versioned(Versions) - @service({ + @service(#{ title: "Widget Service", }) namespace DemoService; diff --git a/website/src/assets/tsp-samples/openapi3/interoperate/main.tsp b/website/src/assets/tsp-samples/openapi3/interoperate/main.tsp index 0d8b255cc6a..e07631b9a69 100644 --- a/website/src/assets/tsp-samples/openapi3/interoperate/main.tsp +++ b/website/src/assets/tsp-samples/openapi3/interoperate/main.tsp @@ -1,6 +1,4 @@ -@service({ - title: "Pet Store Service", -}) +@service(#{ title: "Pet Store Service" }) namespace PetStore; op ping(): void; diff --git a/website/src/assets/tsp-samples/tooling/formatter/file.noformat.tsp b/website/src/assets/tsp-samples/tooling/formatter/file.noformat.tsp index 4610d02bf83..38159ddae95 100644 --- a/website/src/assets/tsp-samples/tooling/formatter/file.noformat.tsp +++ b/website/src/assets/tsp-samples/tooling/formatter/file.noformat.tsp @@ -2,7 +2,7 @@ import "@typespec/http"; using TypeSpec.Http; -@service({ title: "Accounting firm" }) namespace MyOrg.Accounting; +@service(#{ title: "Accounting firm" }) namespace MyOrg.Accounting; diff --git a/website/src/assets/tsp-samples/tooling/formatter/formatted.tsp b/website/src/assets/tsp-samples/tooling/formatter/formatted.tsp index c4e358a88c4..a1d09d70553 100644 --- a/website/src/assets/tsp-samples/tooling/formatter/formatted.tsp +++ b/website/src/assets/tsp-samples/tooling/formatter/formatted.tsp @@ -2,9 +2,7 @@ import "@typespec/http"; using TypeSpec.Http; -@service({ - title: "Accounting firm", -}) +@service(#{ title: "Accounting firm" }) namespace MyOrg.Accounting; model Account { diff --git a/website/src/content/docs/docs/getting-started/getting-started-rest/01-setup-basic-syntax.mdx b/website/src/content/docs/docs/getting-started/getting-started-rest/01-setup-basic-syntax.mdx index 0a2c50ce1fe..4c029170cf7 100644 --- a/website/src/content/docs/docs/getting-started/getting-started-rest/01-setup-basic-syntax.mdx +++ b/website/src/content/docs/docs/getting-started/getting-started-rest/01-setup-basic-syntax.mdx @@ -95,7 +95,7 @@ import "@typespec/http"; using TypeSpec.Http; // highlight-start -@service({ +@service(#{ title: "Pet Store", }) @server("https://example.com", "Single server endpoint") @@ -124,9 +124,7 @@ import "@typespec/http"; using TypeSpec.Http; -@service({ - title: "Pet Store", -}) +@service(#{ title: "Pet Store" }) @server("https://example.com", "Single server endpoint") // highlight-next-line @@ -155,9 +153,7 @@ import "@typespec/http"; using TypeSpec.Http; -@service({ - title: "Pet Store", -}) +@service(#{ title: "Pet Store" }) @server("https://example.com", "Single server endpoint") namespace PetStore; @@ -196,9 +192,7 @@ import "@typespec/http"; using TypeSpec.Http; -@service({ - title: "Pet Store", -}) +@service(#{ title: "Pet Store" }) @server("https://example.com", "Single server endpoint") namespace PetStore; diff --git a/website/src/content/docs/docs/getting-started/getting-started-rest/02-operations-responses.md b/website/src/content/docs/docs/getting-started/getting-started-rest/02-operations-responses.md index d787ba1a7da..ed0d35f4cdc 100644 --- a/website/src/content/docs/docs/getting-started/getting-started-rest/02-operations-responses.md +++ b/website/src/content/docs/docs/getting-started/getting-started-rest/02-operations-responses.md @@ -20,9 +20,7 @@ import "@typespec/http"; using TypeSpec.Http; -@service({ - title: "Pet Store", -}) +@service(#{ title: "Pet Store" }) @server("https://example.com", "Single server endpoint") namespace PetStore; @@ -143,9 +141,7 @@ import "@typespec/http"; using TypeSpec.Http; -@service({ - title: "Pet Store", -}) +@service(#{ title: "Pet Store" }) @server("https://example.com", "Single server endpoint") namespace PetStore; diff --git a/website/src/content/docs/docs/getting-started/getting-started-rest/03-handling-errors.md b/website/src/content/docs/docs/getting-started/getting-started-rest/03-handling-errors.md index 7fe7643d049..a770d24289b 100644 --- a/website/src/content/docs/docs/getting-started/getting-started-rest/03-handling-errors.md +++ b/website/src/content/docs/docs/getting-started/getting-started-rest/03-handling-errors.md @@ -29,9 +29,7 @@ import "@typespec/http"; using TypeSpec.Http; -@service({ - title: "Pet Store", -}) +@service(#{ title: "Pet Store" }) @server("https://example.com", "Single server endpoint") namespace PetStore; diff --git a/website/src/content/docs/docs/getting-started/getting-started-rest/04-common-parameters.md b/website/src/content/docs/docs/getting-started/getting-started-rest/04-common-parameters.md index 9f3966c84a6..eff73e0d535 100644 --- a/website/src/content/docs/docs/getting-started/getting-started-rest/04-common-parameters.md +++ b/website/src/content/docs/docs/getting-started/getting-started-rest/04-common-parameters.md @@ -19,9 +19,7 @@ import "@typespec/http"; using TypeSpec.Http; -@service({ - title: "Pet Store", -}) +@service(#{ title: "Pet Store" }) @server("https://example.com", "Single server endpoint") namespace PetStore; @@ -76,9 +74,7 @@ import "@typespec/http"; using TypeSpec.Http; -@service({ - title: "Pet Store", -}) +@service(#{ title: "Pet Store" }) @server("https://example.com", "Single server endpoint") namespace PetStore; diff --git a/website/src/content/docs/docs/getting-started/getting-started-rest/05-authentication.md b/website/src/content/docs/docs/getting-started/getting-started-rest/05-authentication.md index 217b72e5ec3..21751376f96 100644 --- a/website/src/content/docs/docs/getting-started/getting-started-rest/05-authentication.md +++ b/website/src/content/docs/docs/getting-started/getting-started-rest/05-authentication.md @@ -21,9 +21,7 @@ import "@typespec/http"; using TypeSpec.Http; -@service({ - title: "Pet Store", -}) +@service(#{ title: "Pet Store" }) @server("https://example.com", "Single server endpoint") namespace PetStore; diff --git a/website/src/content/docs/docs/getting-started/getting-started-rest/06-versioning.mdx b/website/src/content/docs/docs/getting-started/getting-started-rest/06-versioning.mdx index afed54909cd..c109dc30ccb 100644 --- a/website/src/content/docs/docs/getting-started/getting-started-rest/06-versioning.mdx +++ b/website/src/content/docs/docs/getting-started/getting-started-rest/06-versioning.mdx @@ -64,9 +64,7 @@ using TypeSpec.Http; // highlight-next-line using TypeSpec.Versioning; -@service({ - title: "Pet Store", -}) +@service(#{ title: "Pet Store" }) @server("https://example.com", "Single server endpoint") // highlight-next-line @versioned(Versions) @@ -122,9 +120,7 @@ import "@typespec/versioning"; using TypeSpec.Http; using TypeSpec.Versioning; -@service({ - title: "Pet Store", -}) +@service(#{ title: "Pet Store" }) @server("https://example.com", "Single server endpoint") @versioned(Versions) namespace PetStore; @@ -181,9 +177,7 @@ import "@typespec/versioning"; using TypeSpec.Http; using TypeSpec.Versioning; -@service({ - title: "Pet Store", -}) +@service(#{ title: "Pet Store" }) @server("https://example.com", "Single server endpoint") @versioned(Versions) namespace PetStore; diff --git a/website/src/content/docs/docs/getting-started/getting-started-rest/07-custom-response-models.md b/website/src/content/docs/docs/getting-started/getting-started-rest/07-custom-response-models.md index e2680dbdcf5..1ffebcec685 100644 --- a/website/src/content/docs/docs/getting-started/getting-started-rest/07-custom-response-models.md +++ b/website/src/content/docs/docs/getting-started/getting-started-rest/07-custom-response-models.md @@ -103,9 +103,7 @@ import "@typespec/versioning"; using TypeSpec.Http; using TypeSpec.Versioning; -@service({ - title: "Pet Store", -}) +@service(#{ title: "Pet Store" }) @server("https://example.com", "Single server endpoint") @versioned(Versions) namespace PetStore; diff --git a/website/src/content/docs/docs/getting-started/typespec-for-openapi-dev.md b/website/src/content/docs/docs/getting-started/typespec-for-openapi-dev.md index 5610e55f92b..f9d36f0a2b5 100644 --- a/website/src/content/docs/docs/getting-started/typespec-for-openapi-dev.md +++ b/website/src/content/docs/docs/getting-started/typespec-for-openapi-dev.md @@ -783,22 +783,20 @@ In OpenAPI, the `info` object [[v2][v2-info], [v3][v3-info]] contains metadata a In TypeSpec this information is specified with [decorators on the namespace][typespec-service-metadata]. -| OpenAPI `info` field | TypeSpec decorator | Notes | -| -------------------- | -------------------- | --------------------------- | -| `title` | `@service({title: }` | TypeSpec built-in decorator | -| `description` | `@doc` | TypeSpec built-in decorator | -| `version` | `@info` | | -| `license` | `@info` | | -| `contact` | `@info` | | +| OpenAPI `info` field | TypeSpec decorator | Notes | +| -------------------- | --------------------- | --------------------------- | +| `title` | `@service(#{title: }` | TypeSpec built-in decorator | +| `description` | `@doc` | TypeSpec built-in decorator | +| `version` | `@info` | | +| `license` | `@info` | | +| `contact` | `@info` | | [typespec-service-metadata]: https://typespec.io/docs/libraries/http/reference/decorators/ ```typespec /** The Contoso Widget Service provides access to the Contoso Widget API. */ -@service({ - title: "Widget Service", -}) -@info({ +@service(#{ title: "Widget Service" }) +@info(#{ contact: { name: "API Support", email: "contact@contoso.com", diff --git a/website/src/content/docs/docs/libraries/openapi/reference/data-types.md b/website/src/content/docs/docs/libraries/openapi/reference/data-types.md index 89aafe6fc64..e0126e204d4 100644 --- a/website/src/content/docs/docs/libraries/openapi/reference/data-types.md +++ b/website/src/content/docs/docs/libraries/openapi/reference/data-types.md @@ -22,6 +22,7 @@ model TypeSpec.OpenAPI.AdditionalInfo | termsOfService? | `url` | A URL to the Terms of Service for the API. MUST be in the format of a URL. | | contact? | [`Contact`](./data-types.md#TypeSpec.OpenAPI.Contact) | The contact information for the exposed API. | | license? | [`License`](./data-types.md#TypeSpec.OpenAPI.License) | The license information for the exposed API. | +| | `unknown` | Additional properties | ### `Contact` {#TypeSpec.OpenAPI.Contact} @@ -33,11 +34,12 @@ model TypeSpec.OpenAPI.Contact #### Properties -| Name | Type | Description | -| ------ | -------- | ------------------------------------------------------------------------------------------------ | -| name? | `string` | The identifying name of the contact person/organization. | -| url? | `url` | The URL pointing to the contact information. MUST be in the format of a URL. | -| email? | `string` | The email address of the contact person/organization. MUST be in the format of an email address. | +| Name | Type | Description | +| ------ | --------- | ------------------------------------------------------------------------------------------------ | +| name? | `string` | The identifying name of the contact person/organization. | +| url? | `url` | The URL pointing to the contact information. MUST be in the format of a URL. | +| email? | `string` | The email address of the contact person/organization. MUST be in the format of an email address. | +| | `unknown` | Additional properties | ### `ExternalDocs` {#TypeSpec.OpenAPI.ExternalDocs} @@ -65,10 +67,11 @@ model TypeSpec.OpenAPI.License #### Properties -| Name | Type | Description | -| ---- | -------- | ---------------------------------------------------------------------- | -| name | `string` | The license name used for the API. | -| url? | `url` | A URL to the license used for the API. MUST be in the format of a URL. | +| Name | Type | Description | +| ---- | --------- | ---------------------------------------------------------------------- | +| name | `string` | The license name used for the API. | +| url? | `url` | A URL to the license used for the API. MUST be in the format of a URL. | +| | `unknown` | Additional properties | ### `TagMetadata` {#TypeSpec.OpenAPI.TagMetadata} diff --git a/website/src/content/docs/docs/libraries/openapi/reference/decorators.md b/website/src/content/docs/docs/libraries/openapi/reference/decorators.md index 10fb0b4ec1b..1fe9c7d4df3 100644 --- a/website/src/content/docs/docs/libraries/openapi/reference/decorators.md +++ b/website/src/content/docs/docs/libraries/openapi/reference/decorators.md @@ -94,7 +94,7 @@ Specify OpenAPI additional information. The service `title` and `version` are already specified using `@service`. ```typespec -@TypeSpec.OpenAPI.info(additionalInfo: TypeSpec.OpenAPI.AdditionalInfo) +@TypeSpec.OpenAPI.info(additionalInfo: valueof TypeSpec.OpenAPI.AdditionalInfo) ``` #### Target @@ -103,9 +103,9 @@ The service `title` and `version` are already specified using `@service`. #### Parameters -| Name | Type | Description | -| -------------- | ------------------------------------------------------------------- | ---------------------- | -| additionalInfo | [`AdditionalInfo`](./data-types.md#TypeSpec.OpenAPI.AdditionalInfo) | Additional information | +| Name | Type | Description | +| -------------- | --------------------------------------------------------------------------- | ---------------------- | +| additionalInfo | [valueof `AdditionalInfo`](./data-types.md#TypeSpec.OpenAPI.AdditionalInfo) | Additional information | ### `@operationId` {#@TypeSpec.OpenAPI.operationId} diff --git a/website/src/content/docs/docs/libraries/versioning/guide.md b/website/src/content/docs/docs/libraries/versioning/guide.md index 7da37b54f82..b0d08bc3d6d 100644 --- a/website/src/content/docs/docs/libraries/versioning/guide.md +++ b/website/src/content/docs/docs/libraries/versioning/guide.md @@ -7,18 +7,14 @@ title: Tutorial The primary role of the TypeSpec.Versioning library is to enable API versioning. Let's start with an API that lacks versioning. ```typespec -@service({ - title: "Contoso Widget Manager", -}) +@service(#{ title: "Contoso Widget Manager" }) namespace Contoso.WidgetManager; ``` To introduce versioning to this API, we need to use the `@versioned` decorator on the namespace and define an enum that outlines the supported versions. ```typespec -@service({ - title: "Contoso Widget Manager", -}) +@service(#{ title: "Contoso Widget Manager" }) @versioned(Contoso.WidgetManager.Versions) namespace Contoso.WidgetManager; @@ -34,9 +30,7 @@ Both versioned and unversioned services can declare their dependencies on versio For example, if our unversioned WidgetManager service depends on the Azure.Core library, we would declare it like this: ```typespec -@service({ - title: "Contoso Widget Manager Unversioned", -}) +@service(#{ title: "Contoso Widget Manager Unversioned" }) @useDependency(Azure.Core.v1_0_Preview_1) namespace Contoso.WidgetManager.Unversioned; ``` @@ -44,9 +38,7 @@ namespace Contoso.WidgetManager.Unversioned; If our versioned WidgetManager service depends on the Azure.Core library, we would declare it like this: ```typespec -@service({ - title: "Contoso Widget Manager", -}) +@service(#{ title: "Contoso Widget Manager" }) @versioned(Contoso.WidgetManager.Versions) namespace Contoso.WidgetManager; @@ -59,9 +51,7 @@ enum Versions { Let's say we introduce a new version to our service, and it uses features from a newer version of the Azure.Core library. We can declare that dependency like this: ```typespec -@service({ - title: "Contoso Widget Manager", -}) +@service(#{ title: "Contoso Widget Manager" }) @versioned(Contoso.WidgetManager.Versions) namespace Contoso.WidgetManager; @@ -83,9 +73,7 @@ using TypeSpec.Versioning; using TypeSpec.Rest; using TypeSpec.Http; -@service({ - title: "Contoso Widget Manager", -}) +@service(#{ title: "Contoso Widget Manager" }) @versioned(Contoso.WidgetManager.Versions) namespace Contoso.WidgetManager; diff --git a/website/src/content/docs/docs/release-notes/release-2022-10-12.md b/website/src/content/docs/docs/release-notes/release-2022-10-12.md index 5af411ad4f6..d9042514afc 100644 --- a/website/src/content/docs/docs/release-notes/release-2022-10-12.md +++ b/website/src/content/docs/docs/release-notes/release-2022-10-12.md @@ -66,7 +66,7 @@ compile(host, "main.tsp"); namespace PetStore; // After -@service({"Pet Store", version: "v1"}) +@service(#{"Pet Store", version: "v1"}) namespace PetStore; ``` diff --git a/website/src/content/docs/docs/release-notes/release-2023-02-07.md b/website/src/content/docs/docs/release-notes/release-2023-02-07.md index 9999ad5cade..026ef099637 100644 --- a/website/src/content/docs/docs/release-notes/release-2023-02-07.md +++ b/website/src/content/docs/docs/release-notes/release-2023-02-07.md @@ -69,9 +69,7 @@ For versioned libraries, `@useDependency` is applied to the version enum members ```typespec @armProviderNamespace -@service({ - title: "Microsoft.Observability", -}) +@service(#{ title: "Microsoft.Observability" }) @versionedDependency( [ [Microsoft.Observability.Versions.v2021_06_13_preview, Azure.Core.Versions.v1_0_Preview_2], @@ -105,9 +103,7 @@ enum Versions { ```typespec @armProviderNamespace -@service({ - title: "Microsoft.Observability", -}) +@service(#{ title: "Microsoft.Observability" }) @versioned(Versions) namespace Microsoft.Observability; @@ -127,10 +123,7 @@ For unversioned libraries that reference versioned libraries, simply replace `@v #### Before (unversioned namespace using versioned library) ```typespec -@service({ - title: "Microsoft.EnvelopeTest", - version: "2021-09-21-preview", -}) +@service(#{ title: "Microsoft.EnvelopeTest", version: "2021-09-21-preview" }) @versionedDependency(Azure.ResourceManager.Versions.v1_0_Preview_1) @armProviderNamespace namespace Microsoft.EnvelopeTest; @@ -139,10 +132,7 @@ namespace Microsoft.EnvelopeTest; #### After (unversioned namespace using versioned library) ```typespec -@service({ - title: "Microsoft.EnvelopeTest", - version: "2021-09-21-preview", -}) +@service(#{ title: "Microsoft.EnvelopeTest", version: "2021-09-21-preview" }) @useDependency(Azure.ResourceManager.Versions.v1_0_Preview_1) @armProviderNamespace namespace Microsoft.EnvelopeTest; diff --git a/website/src/content/docs/docs/standard-library/built-in-decorators.md b/website/src/content/docs/docs/standard-library/built-in-decorators.md index 17e5776a4c3..f03bcb0b044 100644 --- a/website/src/content/docs/docs/standard-library/built-in-decorators.md +++ b/website/src/content/docs/docs/standard-library/built-in-decorators.md @@ -1217,7 +1217,7 @@ scalar Password is string; Mark this namespace as describing a service and configure service properties. ```typespec -@service(options?: ServiceOptions) +@service(options?: valueof ServiceOptions) ``` #### Target @@ -1227,7 +1227,7 @@ Mark this namespace as describing a service and configure service properties. #### Parameters | Name | Type | Description | |------|------|-------------| -| options | [`ServiceOptions`](./built-in-data-types.md#ServiceOptions) | Optional configuration for the service. | +| options | [valueof `ServiceOptions`](./built-in-data-types.md#ServiceOptions) | Optional configuration for the service. | #### Examples @@ -1239,14 +1239,14 @@ namespace PetStore; ##### Setting service title ```typespec -@service({title: "Pet store"}) +@service(#{title: "Pet store"}) namespace PetStore; ``` ##### Setting service version ```typespec -@service({version: "1.0"}) +@service(#{version: "1.0"}) namespace PetStore; ```