-
Notifications
You must be signed in to change notification settings - Fork 243
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[OpenAPI 3 Emitter] Reuse Operation IDs With Identical Values In @ope…
…rationid Decorators For Shared Routes (#6157) Fix: #5513 This pull request introduces changes to reuse operation IDs when all `@operationId` decorators share the same value, which improve the usability for client code generation to leverage the shared operation ID. --------- Co-authored-by: albertxavier100 <[email protected]> Co-authored-by: Copilot <[email protected]> Co-authored-by: albertxavier100 <[email protected]> Co-authored-by: Timothee Guerin <[email protected]>
- Loading branch information
1 parent
ceec016
commit 134f7e7
Showing
3 changed files
with
72 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
--- | ||
changeKind: feature | ||
packages: | ||
- "@typespec/openapi3" | ||
--- | ||
|
||
Shared operations operationId can now be set if they all share the same value provided by `@operationId` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
import { expect, it } from "vitest"; | ||
import { OpenAPI3Document } from "../src/types.js"; | ||
import { worksFor } from "./works-for.js"; | ||
|
||
interface Case { | ||
description: string; | ||
code: string; | ||
expectedOperationId: string; | ||
} | ||
|
||
const testCases: Case[] = [ | ||
{ | ||
description: "should reuse on the same operation IDs", | ||
code: createCode("op1", "op1", "op1"), | ||
expectedOperationId: "op1", | ||
}, | ||
{ | ||
description: "should concat with different operation IDs", | ||
code: createCode("op1", "op1", "op2"), | ||
expectedOperationId: "op1_op1_op2", | ||
}, | ||
{ | ||
description: "should concat with partial operation IDs", | ||
code: createCode(undefined, "op1", "op1"), | ||
expectedOperationId: "getWidget1_op1_op1", | ||
}, | ||
{ | ||
description: "should concat with no operation IDs", | ||
code: createCode(), | ||
expectedOperationId: "getWidget1_getWidget2_getWidget3", | ||
}, | ||
]; | ||
|
||
worksFor(["3.0.0", "3.1.0"], ({ openApiFor }) => { | ||
it.each(testCases)("$description", async (c: Case) => { | ||
const res: OpenAPI3Document = await openApiFor(c.code); | ||
expect(res.paths["/{id}"].get?.operationId).toBe(c.expectedOperationId); | ||
}); | ||
}); | ||
|
||
function createCode(id1?: string, id2?: string, id3?: string) { | ||
return ` | ||
@service | ||
namespace DemoService; | ||
${createOperationCodeBlock(1, id1)} | ||
${createOperationCodeBlock(2, id2)} | ||
${createOperationCodeBlock(3, id3)} | ||
`; | ||
} | ||
|
||
function createOperationCodeBlock(operationIndex: number, id?: string) { | ||
return ` | ||
@sharedRoute | ||
${createOperationIdDecorator(id)} | ||
op getWidget${operationIndex}(@path id: string): void; | ||
`; | ||
} | ||
|
||
function createOperationIdDecorator(id?: string) { | ||
return id ? `@operationId("${id}")` : ""; | ||
} |