From 6346e074cb7bb254c12ef6db9ddac96c8e6054c2 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 30 Jan 2026 20:28:59 +0000 Subject: [PATCH 1/4] Initial plan From 66c3c1c9886c4d6aa5f1e9b4b00ed557e8eadf3a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 30 Jan 2026 21:02:24 +0000 Subject: [PATCH 2/4] Add comment-highlights plugin for Expressive Code - Create custom plugin to handle // highlight-start, // highlight-end, and // highlight-next-line comments - Plugin removes marker comments and applies text markers to highlighted lines - Add plugin to Expressive Code configuration Co-authored-by: timotheeguerin <1031227+timotheeguerin@users.noreply.github.com> --- .../astro-utils/src/expressive-code/config.ts | 2 + .../plugins/comment-highlights.ts | 106 ++++++++++++++++++ 2 files changed, 108 insertions(+) create mode 100644 packages/astro-utils/src/expressive-code/plugins/comment-highlights.ts diff --git a/packages/astro-utils/src/expressive-code/config.ts b/packages/astro-utils/src/expressive-code/config.ts index 2cf253e0275..59c169a10d0 100644 --- a/packages/astro-utils/src/expressive-code/config.ts +++ b/packages/astro-utils/src/expressive-code/config.ts @@ -1,6 +1,7 @@ // @ts-check import { addClassName } from "@expressive-code/core/hast"; import { defineEcConfig } from "astro-expressive-code"; +import commentHighlights from "./plugins/comment-highlights.js"; import tspTryitCode from "./plugins/tsp-tryit-code.js"; export function defineTypeSpecEcConfig(base: string) { @@ -42,6 +43,7 @@ export function defineTypeSpecEcConfig(base: string) { }, }, }, + commentHighlights(), tspTryitCode(base + "playground/"), ], }); diff --git a/packages/astro-utils/src/expressive-code/plugins/comment-highlights.ts b/packages/astro-utils/src/expressive-code/plugins/comment-highlights.ts new file mode 100644 index 00000000000..af897f00ba5 --- /dev/null +++ b/packages/astro-utils/src/expressive-code/plugins/comment-highlights.ts @@ -0,0 +1,106 @@ +import { definePlugin } from "@expressive-code/core"; + +/** + * Plugin to handle comment-based highlight markers in code blocks. + * Supports: + * - // highlight-start ... // highlight-end + * - // highlight-next-line + */ +export default function commentHighlightsPlugin() { + // Store the line numbers to highlight per code block + const highlightMap = new WeakMap(); + + console.log('[comment-highlights] Plugin loaded'); + + return definePlugin({ + name: "comment-highlights", + hooks: { + preprocessCode: ({ codeBlock }) => { + const lines = codeBlock.getLines(); + const linesToHighlight = new Set(); + const linesToDelete: number[] = []; + + for (let i = 0; i < lines.length; i++) { + const lineText = lines[i].text.trim(); + + // Debug: log all lines that contain "highlight" + if (lineText.includes("highlight")) { + console.log('[comment-highlights] Line', i, 'contains highlight:', JSON.stringify(lineText)); + } + + // Check for highlight-next-line + if (lineText === "// highlight-next-line") { + if (i + 1 < lines.length) { + linesToHighlight.add(i + 1); + } + linesToDelete.push(i); + console.log('[comment-highlights] Found highlight-next-line at', i); + } + // Check for highlight-start + else if (lineText === "// highlight-start") { + linesToDelete.push(i); + console.log('[comment-highlights] Found highlight-start at', i); + // Find the matching highlight-end + let j = i + 1; + while (j < lines.length) { + const endLineText = lines[j].text.trim(); + if (endLineText === "// highlight-end") { + linesToDelete.push(j); + console.log('[comment-highlights] Found highlight-end at', j); + break; + } + linesToHighlight.add(j); + j++; + } + } + } + + console.log('[comment-highlights] Lines to highlight:', Array.from(linesToHighlight)); + console.log('[comment-highlights] Lines to delete:', linesToDelete); + + // Delete marker lines (in reverse order to maintain indices) + if (linesToDelete.length > 0) { + codeBlock.deleteLines(linesToDelete); + } + + // Adjust line indices after deletion and store them + const deletedLinesBefore = (lineIndex: number) => { + return linesToDelete.filter((deletedIndex) => deletedIndex < lineIndex).length; + }; + + const adjustedLineNumbers: number[] = []; + linesToHighlight.forEach((lineIndex) => { + const adjustedIndex = lineIndex - deletedLinesBefore(lineIndex); + const line = codeBlock.getLine(adjustedIndex); + if (line && !line.text.trim().startsWith("//")) { + // Use 1-based line number + adjustedLineNumbers.push(adjustedIndex + 1); + } + }); + + console.log('[comment-highlights] Adjusted line numbers:', adjustedLineNumbers); + + // Store the line numbers to be used in preprocessMetadata + if (adjustedLineNumbers.length > 0) { + highlightMap.set(codeBlock, adjustedLineNumbers); + } + }, + preprocessMetadata: ({ codeBlock }) => { + const lineNumbers = highlightMap.get(codeBlock); + if (lineNumbers) { + const props = codeBlock.props as any; + const currentMark = props.mark || []; + const markArray = Array.isArray(currentMark) ? [...currentMark] : [currentMark]; + + lineNumbers.forEach((lineNum) => { + markArray.push(lineNum); + }); + + props.mark = markArray; + console.log('[comment-highlights] Set mark prop to:', props.mark); + } + }, + }, + }); +} + From 64c48e40dd9e2b8a9c2359c36f6367c5cf73196b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 30 Jan 2026 21:08:08 +0000 Subject: [PATCH 3/4] Simplify comment-highlights plugin logic - Remove debug logging - Consolidate into two hooks: preprocessCode and preprocessMetadata - Comments are successfully being removed from rendered code Co-authored-by: timotheeguerin <1031227+timotheeguerin@users.noreply.github.com> --- .../plugins/comment-highlights.ts | 64 ++++++------------- 1 file changed, 20 insertions(+), 44 deletions(-) diff --git a/packages/astro-utils/src/expressive-code/plugins/comment-highlights.ts b/packages/astro-utils/src/expressive-code/plugins/comment-highlights.ts index af897f00ba5..14a9eed2a51 100644 --- a/packages/astro-utils/src/expressive-code/plugins/comment-highlights.ts +++ b/packages/astro-utils/src/expressive-code/plugins/comment-highlights.ts @@ -8,9 +8,7 @@ import { definePlugin } from "@expressive-code/core"; */ export default function commentHighlightsPlugin() { // Store the line numbers to highlight per code block - const highlightMap = new WeakMap(); - - console.log('[comment-highlights] Plugin loaded'); + const highlightData = new WeakMap(); return definePlugin({ name: "comment-highlights", @@ -23,30 +21,22 @@ export default function commentHighlightsPlugin() { for (let i = 0; i < lines.length; i++) { const lineText = lines[i].text.trim(); - // Debug: log all lines that contain "highlight" - if (lineText.includes("highlight")) { - console.log('[comment-highlights] Line', i, 'contains highlight:', JSON.stringify(lineText)); - } - // Check for highlight-next-line if (lineText === "// highlight-next-line") { if (i + 1 < lines.length) { linesToHighlight.add(i + 1); } linesToDelete.push(i); - console.log('[comment-highlights] Found highlight-next-line at', i); } // Check for highlight-start else if (lineText === "// highlight-start") { linesToDelete.push(i); - console.log('[comment-highlights] Found highlight-start at', i); // Find the matching highlight-end let j = i + 1; while (j < lines.length) { const endLineText = lines[j].text.trim(); if (endLineText === "// highlight-end") { linesToDelete.push(j); - console.log('[comment-highlights] Found highlight-end at', j); break; } linesToHighlight.add(j); @@ -55,49 +45,35 @@ export default function commentHighlightsPlugin() { } } - console.log('[comment-highlights] Lines to highlight:', Array.from(linesToHighlight)); - console.log('[comment-highlights] Lines to delete:', linesToDelete); - - // Delete marker lines (in reverse order to maintain indices) + // If we found any markers, process them if (linesToDelete.length > 0) { + // Delete marker lines codeBlock.deleteLines(linesToDelete); - } - // Adjust line indices after deletion and store them - const deletedLinesBefore = (lineIndex: number) => { - return linesToDelete.filter((deletedIndex) => deletedIndex < lineIndex).length; - }; + // Adjust line indices after deletion + const deletedLinesBefore = (lineIndex: number) => { + return linesToDelete.filter((deletedIndex) => deletedIndex < lineIndex).length; + }; - const adjustedLineNumbers: number[] = []; - linesToHighlight.forEach((lineIndex) => { - const adjustedIndex = lineIndex - deletedLinesBefore(lineIndex); - const line = codeBlock.getLine(adjustedIndex); - if (line && !line.text.trim().startsWith("//")) { - // Use 1-based line number + const adjustedLineNumbers: number[] = []; + linesToHighlight.forEach((lineIndex) => { + const adjustedIndex = lineIndex - deletedLinesBefore(lineIndex); + // Store 1-based line numbers adjustedLineNumbers.push(adjustedIndex + 1); - } - }); - - console.log('[comment-highlights] Adjusted line numbers:', adjustedLineNumbers); + }); - // Store the line numbers to be used in preprocessMetadata - if (adjustedLineNumbers.length > 0) { - highlightMap.set(codeBlock, adjustedLineNumbers); + // Store for preprocessMetadata hook + if (adjustedLineNumbers.length > 0) { + highlightData.set(codeBlock, adjustedLineNumbers); + } } }, preprocessMetadata: ({ codeBlock }) => { - const lineNumbers = highlightMap.get(codeBlock); - if (lineNumbers) { + const lineNumbers = highlightData.get(codeBlock); + if (lineNumbers && lineNumbers.length > 0) { + // Set the mark prop which will be processed by the text-markers plugin const props = codeBlock.props as any; - const currentMark = props.mark || []; - const markArray = Array.isArray(currentMark) ? [...currentMark] : [currentMark]; - - lineNumbers.forEach((lineNum) => { - markArray.push(lineNum); - }); - - props.mark = markArray; - console.log('[comment-highlights] Set mark prop to:', props.mark); + props.mark = lineNumbers; } }, }, From 7f31e0a6256c623643763f83ece5c843534b9967 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 30 Jan 2026 23:01:40 +0000 Subject: [PATCH 4/4] Convert highlight comments to mark syntax - Remove custom comment-highlights plugin - Convert // highlight-start, // highlight-end, and // highlight-next-line comments to mark={} syntax in code fences - Update all tutorial documentation files in getting-started/getting-started-rest - Use Expressive Code's native text-markers plugin with mark={} meta syntax Co-authored-by: timotheeguerin <1031227+timotheeguerin@users.noreply.github.com> --- .../astro-utils/src/expressive-code/config.ts | 2 - .../plugins/comment-highlights.ts | 82 ------------------- .../01-setup-basic-syntax.mdx | 16 +--- .../02-operations-responses.md | 12 +-- .../03-handling-errors.md | 9 +- .../04-common-parameters.md | 17 +--- .../getting-started-rest/05-authentication.md | 19 +---- .../getting-started-rest/06-versioning.mdx | 19 +---- .../07-custom-response-models.md | 13 +-- 9 files changed, 17 insertions(+), 172 deletions(-) delete mode 100644 packages/astro-utils/src/expressive-code/plugins/comment-highlights.ts diff --git a/packages/astro-utils/src/expressive-code/config.ts b/packages/astro-utils/src/expressive-code/config.ts index 59c169a10d0..2cf253e0275 100644 --- a/packages/astro-utils/src/expressive-code/config.ts +++ b/packages/astro-utils/src/expressive-code/config.ts @@ -1,7 +1,6 @@ // @ts-check import { addClassName } from "@expressive-code/core/hast"; import { defineEcConfig } from "astro-expressive-code"; -import commentHighlights from "./plugins/comment-highlights.js"; import tspTryitCode from "./plugins/tsp-tryit-code.js"; export function defineTypeSpecEcConfig(base: string) { @@ -43,7 +42,6 @@ export function defineTypeSpecEcConfig(base: string) { }, }, }, - commentHighlights(), tspTryitCode(base + "playground/"), ], }); diff --git a/packages/astro-utils/src/expressive-code/plugins/comment-highlights.ts b/packages/astro-utils/src/expressive-code/plugins/comment-highlights.ts deleted file mode 100644 index 14a9eed2a51..00000000000 --- a/packages/astro-utils/src/expressive-code/plugins/comment-highlights.ts +++ /dev/null @@ -1,82 +0,0 @@ -import { definePlugin } from "@expressive-code/core"; - -/** - * Plugin to handle comment-based highlight markers in code blocks. - * Supports: - * - // highlight-start ... // highlight-end - * - // highlight-next-line - */ -export default function commentHighlightsPlugin() { - // Store the line numbers to highlight per code block - const highlightData = new WeakMap(); - - return definePlugin({ - name: "comment-highlights", - hooks: { - preprocessCode: ({ codeBlock }) => { - const lines = codeBlock.getLines(); - const linesToHighlight = new Set(); - const linesToDelete: number[] = []; - - for (let i = 0; i < lines.length; i++) { - const lineText = lines[i].text.trim(); - - // Check for highlight-next-line - if (lineText === "// highlight-next-line") { - if (i + 1 < lines.length) { - linesToHighlight.add(i + 1); - } - linesToDelete.push(i); - } - // Check for highlight-start - else if (lineText === "// highlight-start") { - linesToDelete.push(i); - // Find the matching highlight-end - let j = i + 1; - while (j < lines.length) { - const endLineText = lines[j].text.trim(); - if (endLineText === "// highlight-end") { - linesToDelete.push(j); - break; - } - linesToHighlight.add(j); - j++; - } - } - } - - // If we found any markers, process them - if (linesToDelete.length > 0) { - // Delete marker lines - codeBlock.deleteLines(linesToDelete); - - // Adjust line indices after deletion - const deletedLinesBefore = (lineIndex: number) => { - return linesToDelete.filter((deletedIndex) => deletedIndex < lineIndex).length; - }; - - const adjustedLineNumbers: number[] = []; - linesToHighlight.forEach((lineIndex) => { - const adjustedIndex = lineIndex - deletedLinesBefore(lineIndex); - // Store 1-based line numbers - adjustedLineNumbers.push(adjustedIndex + 1); - }); - - // Store for preprocessMetadata hook - if (adjustedLineNumbers.length > 0) { - highlightData.set(codeBlock, adjustedLineNumbers); - } - } - }, - preprocessMetadata: ({ codeBlock }) => { - const lineNumbers = highlightData.get(codeBlock); - if (lineNumbers && lineNumbers.length > 0) { - // Set the mark prop which will be processed by the text-markers plugin - const props = codeBlock.props as any; - props.mark = lineNumbers; - } - }, - }, - }); -} - 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 40267bc99b8..a1efdfce16b 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 @@ -92,16 +92,14 @@ A REST service in TypeSpec is defined using the [`@service`](../../../standard-l Let's start by defining a simple REST service for a Pet Store: -```tsp title=main.tsp tryit="{"emit": ["@typespec/openapi3"]}" +```tsp title=main.tsp tryit="{"emit": ["@typespec/openapi3"]}" mark={4-7} import "@typespec/http"; using Http; -// highlight-start @service(#{ title: "Pet Store", }) @server("https://example.com", "Single server endpoint") -// highlight-end ``` In this example: @@ -121,7 +119,7 @@ In this example: Let's create a namespace for our Pet Store service: -```tsp title=main.tsp tryit="{"emit": ["@typespec/openapi3"]}" +```tsp title=main.tsp tryit="{"emit": ["@typespec/openapi3"]}" mark={8} import "@typespec/http"; using Http; @@ -129,7 +127,6 @@ using Http; @service(#{ title: "Pet Store" }) @server("https://example.com", "Single server endpoint") -// highlight-next-line namespace PetStore; ``` @@ -150,7 +147,7 @@ In TypeSpec, a [model](../../language-basics/models.md) is a fundamental buildin Let's define a simple model for a `Pet`: -```tsp title=main.tsp tryit="{"emit": ["@typespec/openapi3"]}" +```tsp title=main.tsp tryit="{"emit": ["@typespec/openapi3"]}" mark={9-22} import "@typespec/http"; using Http; @@ -159,7 +156,6 @@ using Http; @server("https://example.com", "Single server endpoint") namespace PetStore; -// highlight-start model Pet { id: int32; name: string; @@ -174,7 +170,6 @@ enum petType { bird: "bird", reptile: "reptile", } -// highlight-end ``` In this example: @@ -189,7 +184,7 @@ In this example: We can add [validation](../../../language-basics/values/#validation) annotations to our model properties to enforce certain constraints: -```tsp title=main.tsp tryit="{"emit": ["@typespec/openapi3"]}" +```tsp title=main.tsp tryit="{"emit": ["@typespec/openapi3"]}" mark={12,15-16} import "@typespec/http"; using Http; @@ -201,13 +196,10 @@ namespace PetStore; model Pet { id: int32; - // highlight-next-line @minLength(1) name: string; - // highlight-next-line @minValue(0) - // highlight-next-line @maxValue(100) age: int32; 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 18650cc2109..215dfe89e0a 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 @@ -17,7 +17,7 @@ Next, we'll discuss how to define CRUD operations for our API. We'll cover opera Let's define the CRUD operations for our `Pet` model: -```tsp title=main.tsp tryit="{"emit": ["@typespec/openapi3"]}" +```tsp title=main.tsp tryit="{"emit": ["@typespec/openapi3"]}" mark={30-60} import "@typespec/http"; using Http; @@ -47,7 +47,6 @@ enum petType { reptile: "reptile", } -// highlight-start @route("/pets") namespace Pets { @get @@ -79,7 +78,6 @@ namespace Pets { @statusCode statusCode: 204; }; } -// highlight-end ``` In this example: @@ -138,7 +136,7 @@ In a real-world API, different operations might return different types of succes Let's update our pet operations to return different status codes based on the outcome. -```tsp title=main.tsp tryit="{"emit": ["@typespec/openapi3"]}" +```tsp title=main.tsp tryit="{"emit": ["@typespec/openapi3"]}" mark={42-43,50-52,59-60} import "@typespec/http"; using Http; @@ -180,31 +178,25 @@ namespace Pets { op getPet(@path petId: int32): { @statusCode statusCode: 200; @body pet: Pet; - // highlight-start } | { @statusCode statusCode: 404; - // highlight-end }; @post op createPet(@body pet: Pet): { @statusCode statusCode: 201; @body newPet: Pet; - // highlight-start } | { @statusCode statusCode: 202; @body acceptedPet: Pet; - // highlight-end }; @put op updatePet(@path petId: int32, @body pet: Pet): { @statusCode statusCode: 200; @body updatedPet: Pet; - // highlight-start } | { @statusCode statusCode: 404; - // highlight-end }; @delete 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 6aa893c46a8..2e98ad8d227 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 @@ -26,7 +26,7 @@ Error models can be used to represent different types of errors that your API mi We'll define models to represent validation errors, not-found errors, and internal server errors: -```tsp title=main.tsp tryit="{"emit": ["@typespec/openapi3"]}" +```tsp title=main.tsp tryit="{"emit": ["@typespec/openapi3"]}" mark={45,55-58,65-76,85-102} import "@typespec/http"; using Http; @@ -71,7 +71,6 @@ namespace Pets { } | { @statusCode statusCode: 404; - // highlight-next-line @body error: NotFoundError; }; @@ -82,19 +81,16 @@ namespace Pets { } | { @statusCode statusCode: 202; @body acceptedPet: Pet; - // highlight-start } | { @statusCode statusCode: 400; @body error: ValidationError; }; - // highlight-end @put op updatePet(@path petId: int32, @body pet: Pet): | { @statusCode statusCode: 200; @body updatedPet: Pet; - // highlight-start } | { @statusCode statusCode: 400; @@ -107,7 +103,6 @@ namespace Pets { | { @statusCode statusCode: 500; @body error: InternalServerError; - // highlight-end }; @delete @@ -116,7 +111,6 @@ namespace Pets { }; } -// highlight-start @error model NotFoundError { code: "NOT_FOUND"; @@ -135,7 +129,6 @@ model InternalServerError { code: "INTERNAL_SERVER_ERROR"; message: string; } -// highlight-end ``` In this example: 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 665421e8d0a..931ef3008ab 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 @@ -16,7 +16,7 @@ Let's start by defining a model for common parameters. This model will include p For the sake of demonstration, we're going to require each API call in our Pet Store service to include a request ID, a locale, and a client version. Let's define a model for these common parameters, which we'll label `requestID`, `locale`, and `clientVersion`: -```tsp title=main.tsp tryit="{"emit": ["@typespec/openapi3"]}" +```tsp title=main.tsp tryit="{"emit": ["@typespec/openapi3"]}" mark={30-39} import "@typespec/http"; using Http; @@ -46,7 +46,6 @@ enum petType { reptile: "reptile", } -// highlight-start model CommonParameters { @header requestID: string; @@ -57,7 +56,6 @@ model CommonParameters { @header clientVersion?: string; } -// highlight-end ``` In this example: @@ -71,7 +69,7 @@ Now that we have defined our common parameters model, let's reuse it across mult ### Example: Reusing Common Parameters in Operations -```tsp title=main.tsp tryit="{"emit": ["@typespec/openapi3"]}" +```tsp title=main.tsp tryit="{"emit": ["@typespec/openapi3"]}" mark={44,50,59,71,90} import "@typespec/http"; using Http; @@ -115,14 +113,12 @@ model CommonParameters { @route("/pets") namespace Pets { @get - // highlight-next-line op listPets(...CommonParameters): { @statusCode statusCode: 200; @body pets: Pet[]; }; @get - // highlight-next-line op getPet(@path petId: int32, ...CommonParameters): { @statusCode statusCode: 200; @body pet: Pet; @@ -132,7 +128,6 @@ namespace Pets { }; @post - // highlight-next-line op createPet(@body pet: Pet, ...CommonParameters): { @statusCode statusCode: 201; @body newPet: Pet; @@ -145,7 +140,6 @@ namespace Pets { }; @put - // highlight-next-line op updatePet(@path petId: int32, @body pet: Pet, ...CommonParameters): | { @statusCode statusCode: 200; @@ -165,7 +159,6 @@ namespace Pets { }; @delete - // highlight-next-line op deletePet(@path petId: int32, ...CommonParameters): { @statusCode statusCode: 204; }; @@ -200,7 +193,7 @@ In this example: Let's take a closer look at how the common parameters model with the `spread` operator is represented in the generated OpenAPI specification by looking at the `deletePet` operation: -```yaml +```yaml mark={14-16,28-45} #### Generated OpenAPI Specification: paths: @@ -214,11 +207,9 @@ paths: schema: type: integer format: int32 - // highlight-start - $ref: "#/components/parameters/CommonParameters.requestID" - $ref: "#/components/parameters/CommonParameters.locale" - $ref: "#/components/parameters/CommonParameters.clientVersion" - // highlight-end responses: "204": description: "There is no content to send for this request, but the headers may be useful." @@ -230,7 +221,6 @@ paths: $ref: "#/components/schemas/NotFoundError" components: parameters: - // highlight-start CommonParameters.clientVersion: name: client-version in: header @@ -249,7 +239,6 @@ components: required: true schema: type: string - // highlight-end schemas: NotFoundError: type: object 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 f1937fb8798..98ebf287f7e 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 @@ -18,7 +18,7 @@ Bearer authentication uses tokens for access control. The server generates a tok Let's update our existing operations by enforcing authentication using the `@useAuth` decorator.We'll add authentication to the operations that modify pet data, such as creating, updating, and deleting pets. We'll also add a new error model for unauthorized access. -```tsp title=main.tsp tryit="{"emit": ["@typespec/openapi3"]}" +```tsp title=main.tsp tryit="{"emit": ["@typespec/openapi3"]}" mark={59,72-75,79,90-92,104,107-109,126-130} import "@typespec/http"; using Http; @@ -77,7 +77,6 @@ namespace Pets { }; @post - // highlight-next-line @useAuth(BearerAuth) op createPet(@body pet: Pet, ...CommonParameters): | { @@ -91,16 +90,13 @@ namespace Pets { | { @statusCode statusCode: 400; @body error: ValidationError; - // highlight-start } | { @statusCode statusCode: 401; @body error: UnauthorizedError; - // highlight-end }; @put - // highlight-next-line @useAuth(BearerAuth) op updatePet(@path petId: int32, @body pet: Pet, ...CommonParameters): | { @@ -112,11 +108,9 @@ namespace Pets { @body error: ValidationError; } | { - // highlight-start @statusCode statusCode: 401; @body error: UnauthorizedError; - // highlight-end } | { @statusCode statusCode: 404; @@ -128,15 +122,12 @@ namespace Pets { }; @delete - // highlight-next-line @useAuth(BearerAuth) op deletePet(@path petId: int32, ...CommonParameters): { @statusCode statusCode: 204; - // highlight-start } | { @statusCode statusCode: 401; @body error: UnauthorizedError; - // highlight-end }; } @@ -153,13 +144,11 @@ model ValidationError { details: string[]; } -// highlight-start @error model UnauthorizedError { code: "UNAUTHORIZED"; message: string; } -// highlight-end @error model InternalServerError { @@ -183,7 +172,7 @@ In this example: Let's take a closer look at how the `@useAuth` decorator affects the generated OpenAPI specification for the `deletePet` operation. -```yaml +```yaml mark={15-16,46-49} paths: /pets/{petId}: delete: @@ -198,10 +187,8 @@ paths: - $ref: "#/components/parameters/CommonParameters.requestID" - $ref: "#/components/parameters/CommonParameters.locale" - $ref: "#/components/parameters/CommonParameters.clientVersion" - // highlight-start security: - BearerAuth: [] - // highlight-end responses: "204": description: "There is no content to send for this request, but the headers may be useful." @@ -231,12 +218,10 @@ components: required: true schema: type: string - // highlight-start securitySchemes: BearerAuth: type: http scheme: bearer - // highlight-end schemas: NotFoundError: type: object 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 41d61f9c0a3..860b816cae2 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 @@ -18,7 +18,7 @@ Before we can use the versioning decorators, we need to add the `@typespec/versi Add the `@typespec/versioning` library to your `package.json` file, in both the `peerDependencies` and `devDependencies` sections. Your updated `package.json` should look like this: -```json +```json mark={9,15} { "name": "typespec-petstore", "version": "0.1.0", @@ -27,14 +27,12 @@ Add the `@typespec/versioning` library to your `package.json` file, in both the "@typespec/compiler": "latest", "@typespec/http": "latest", "@typespec/openapi3": "latest", - // highlight-next-line "@typespec/versioning": "latest" }, "devDependencies": { "@typespec/compiler": "latest", "@typespec/http": "latest", "@typespec/openapi3": "latest", - // highlight-next-line "@typespec/versioning": "latest" }, "private": true @@ -57,27 +55,22 @@ The [`@versioned`](../../../libraries/versioning/reference/decorators/#@TypeSpec Let's define two versions of our API, `v1` and `v2`: -```tsp title=main.tsp tryit="{"emit": ["@typespec/openapi3"]}" +```tsp title=main.tsp tryit="{"emit": ["@typespec/openapi3"]}" mark={2,5,9,12-15} import "@typespec/http"; -// highlight-next-line import "@typespec/versioning"; using Http; -// highlight-next-line using Versioning; @service(#{ title: "Pet Store" }) @server("https://example.com", "Single server endpoint") -// highlight-next-line @versioned(Versions) namespace PetStore; -// highlight-start enum Versions { v1: "1.0", v2: "2.0", } -// highlight-end ``` In this example: @@ -115,7 +108,7 @@ The [`@added`](../../../libraries/versioning/reference/decorators/#@TypeSpec.Ver Let's add a `Toy` model that is only available in version 2 of the API: -```tsp title=main.tsp tryit="{"emit": ["@typespec/openapi3"]}" +```tsp title=main.tsp tryit="{"emit": ["@typespec/openapi3"]}" mark={38-42} import "@typespec/http"; import "@typespec/versioning"; @@ -153,13 +146,11 @@ enum petType { reptile: "reptile", } -// highlight-start @added(Versions.v2) model Toy { id: int32; name: string; } -// highlight-end ``` In this example: @@ -172,7 +163,7 @@ Let's define version-specific operations to manage toys for pets. These operatio ### Example: Adding Version-Specific Operations -```tsp title=main.tsp tryit="{"emit": ["@typespec/openapi3"]}" +```tsp title=main.tsp tryit="{"emit": ["@typespec/openapi3"]}" mark={125-180} import "@typespec/http"; import "@typespec/versioning"; @@ -297,7 +288,6 @@ namespace Pets { @body error: UnauthorizedError; }; - // highlight-start @route("{petId}/toys") namespace Toys { @added(Versions.v2) @@ -354,7 +344,6 @@ namespace Pets { @body error: UnauthorizedError; }; } - // highlight-end } @error 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 f26fadc8231..32b97c979a9 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 @@ -98,7 +98,7 @@ Now that we have defined our custom response models, let's use them in our API o ### Example: Applying Custom Response Models to Operations -```tsp title=main.tsp tryit="{"emit": ["@typespec/openapi3"]}" +```tsp title=main.tsp tryit="{"emit": ["@typespec/openapi3"]}" mark={55-97,102,105,108-112,116-121,125} import "@typespec/http"; import "@typespec/versioning"; @@ -153,7 +153,6 @@ model CommonParameters { clientVersion?: string; } -// highlight-start model PetListResponse { ...OkResponse; ...Body; @@ -197,44 +196,34 @@ model PetSuccessResponse { model PetNoContentResponse { ...NoContentResponse; } -// highlight-end @route("/pets") namespace Pets { @get - // highlight-next-line op listPets(...CommonParameters): PetListResponse; @get - // highlight-start op getPet(@path petId: int32, @header ifMatch?: string): PetResponse | PetNotFoundResponse; - // highlight-end @useAuth(BearerAuth) @post - // highlight-start op createPet(@body pet: Pet): | PetCreatedResponse | PetAcceptedResponse | PetErrorResponse | PetUnauthorizedResponse; - // highlight-end @useAuth(BearerAuth) @put - // highlight-start op updatePet(@path petId: int32, @body pet: Pet): | PetResponse | PetErrorResponse | PetUnauthorizedResponse | PetNotFoundResponse | InternalServerErrorResponse; - // highlight-end @useAuth(BearerAuth) @delete - // highlight-start op deletePet(@path petId: int32): PetNoContentResponse | PetUnauthorizedResponse; - // highlight-end @route("{petId}/toys") namespace Toys {