diff --git a/.chronus/changes/termsOfServiceUrlCheck-2024-8-23-12-59-15.md b/.chronus/changes/termsOfServiceUrlCheck-2024-8-23-12-59-15.md new file mode 100644 index 0000000000..541f10403d --- /dev/null +++ b/.chronus/changes/termsOfServiceUrlCheck-2024-8-23-12-59-15.md @@ -0,0 +1,7 @@ +--- +changeKind: fix +packages: + - "@typespec/openapi" +--- + +`@info` decorator validate `termsOfService` is a valid url \ No newline at end of file diff --git a/packages/openapi/src/decorators.ts b/packages/openapi/src/decorators.ts index d8d41ac379..bf2dae3acf 100644 --- a/packages/openapi/src/decorators.ts +++ b/packages/openapi/src/decorators.ts @@ -185,6 +185,11 @@ export const $info: InfoDecorator = ( if (data === undefined) { return; } + if (data.termsOfService) { + if (!validateIsUri(context, data.termsOfService, "TermsOfService")) { + return; + } + } setInfo(context.program, entity, data); }; @@ -214,3 +219,17 @@ export function resolveInfo(program: Program, entity: Namespace): AdditionalInfo function omitUndefined>(data: T): T { return Object.fromEntries(Object.entries(data).filter(([k, v]) => v !== undefined)) as any; } + +function validateIsUri(context: DecoratorContext, url: string, propertyName: string) { + try { + new URL(url); + return true; + } catch { + reportDiagnostic(context.program, { + code: "not-url", + target: context.getArgumentTarget(0)!, + format: { property: propertyName, value: url }, + }); + return false; + } +} diff --git a/packages/openapi/src/lib.ts b/packages/openapi/src/lib.ts index 0c5c097fba..7201672536 100644 --- a/packages/openapi/src/lib.ts +++ b/packages/openapi/src/lib.ts @@ -16,6 +16,12 @@ export const $lib = createTypeSpecLibrary({ parameter: paramMessage`Duplicate parameter key: '${"value"}'. Check @friendlyName decorators and overlap with types in TypeSpec or service namespace.`, }, }, + "not-url": { + severity: "error", + messages: { + default: paramMessage`${"property"}: ${"value"} is not a valid URL.`, + }, + }, }, }); diff --git a/packages/openapi/test/decorators.test.ts b/packages/openapi/test/decorators.test.ts index dbc2b394a3..87cf1d6b52 100644 --- a/packages/openapi/test/decorators.test.ts +++ b/packages/openapi/test/decorators.test.ts @@ -152,6 +152,18 @@ describe("openapi: decorators", () => { }); describe("@info", () => { + it("emit diagnostic if termsOfService is not a valid url", async () => { + const diagnostics = await runner.diagnose(` + @info({termsOfService:"notvalidurl"}) + @test namespace Service {} + `); + + expectDiagnostics(diagnostics, { + code: "@typespec/openapi/not-url", + message: "TermsOfService: notvalidurl is not a valid URL.", + }); + }); + it("emit diagnostic if use on non namespace", async () => { const diagnostics = await runner.diagnose(` @info({})