From e9797b0f5fa02d9c8fed0b4c033605cd5365f6eb Mon Sep 17 00:00:00 2001 From: Sarah Soutoul Date: Tue, 21 Jul 2026 11:55:17 +0200 Subject: [PATCH 1/4] fix(typedoc): stop multi-@example rendering from inserting a spurious comma The "Examples" catch-all replacement joined values by splitting the captured group on every space, which broke apart example values with internal spaces (e.g. array literals like `["/orgs/:slug", "/orgs/:slug/(.*)"]`) and rejoined them with ", ", producing a `,,`. This surfaced in the generated `AuthenticateRequestOptions` / `ClerkMiddlewareOptions` reference tables. Now joins the backtick-delimited examples directly, preserving each value's internal spacing. Adds a regression test. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../typedoc-multi-example-double-comma.md | 5 ++++ .../__tests__/catch-all-replacements.test.ts | 27 +++++++++++++++++++ .typedoc/custom-plugin.mjs | 7 ++++- 3 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 .changeset/typedoc-multi-example-double-comma.md create mode 100644 .typedoc/__tests__/catch-all-replacements.test.ts diff --git a/.changeset/typedoc-multi-example-double-comma.md b/.changeset/typedoc-multi-example-double-comma.md new file mode 100644 index 00000000000..cf3413af303 --- /dev/null +++ b/.changeset/typedoc-multi-example-double-comma.md @@ -0,0 +1,5 @@ +--- +'@clerk/backend': patch +--- + +Fix the Typedoc generator inserting a spurious extra comma inside multi-`@example` values. The "Examples" replacement split the captured group on every space, which broke apart example values containing internal spaces (e.g. array literals like `["/orgs/:slug", "/orgs/:slug/(.*)"]`) and rejoined them with `, `, producing `,,`. It now joins the backtick-delimited examples directly. Generated-output-only change; no runtime behavior is affected. diff --git a/.typedoc/__tests__/catch-all-replacements.test.ts b/.typedoc/__tests__/catch-all-replacements.test.ts new file mode 100644 index 00000000000..c987188d124 --- /dev/null +++ b/.typedoc/__tests__/catch-all-replacements.test.ts @@ -0,0 +1,27 @@ +import { describe, expect, it } from 'vitest'; + +// @ts-expect-error — .mjs plugin has no type declarations +import { applyCatchAllMdReplacements } from '../custom-plugin.mjs'; + +/** + * Unit coverage for the `getCatchAllReplacements()` rules exercised through the + * exported `applyCatchAllMdReplacements()` entry point. + */ +describe('applyCatchAllMdReplacements', () => { + it('renders a single `@example` as "Example: `value`."', () => { + expect(applyCatchAllMdReplacements('**Example** `foo`')).toBe('Example: `foo`.'); + }); + + it('joins multiple `@example` blocks with ", "', () => { + expect(applyCatchAllMdReplacements('**Examples** `a` `b` `c`')).toBe('Examples: `a`, `b`, `c`.'); + }); + + it('does not corrupt examples that contain internal spaces', () => { + // Regression: splitting the captured group on ' ' rejoined each example's + // internal spaces with ", ", producing a spurious `,,` inside array literals. + const input = '**Examples** `["/orgs/:slug", "/orgs/:slug/(.*)"]` `["/orgs/:id", "/orgs/:id/(.*)"]`'; + expect(applyCatchAllMdReplacements(input)).toBe( + 'Examples: `["/orgs/:slug", "/orgs/:slug/(.*)"]`, `["/orgs/:id", "/orgs/:id/(.*)"]`.', + ); + }); +}); diff --git a/.typedoc/custom-plugin.mjs b/.typedoc/custom-plugin.mjs index c0e49d5ceb4..854ef6f154d 100644 --- a/.typedoc/custom-plugin.mjs +++ b/.typedoc/custom-plugin.mjs @@ -395,7 +395,12 @@ function getCatchAllReplacements() { */ pattern: /\*\*Examples\*\* ((?:`[^`]+`)(?: `[^`]+`)*)/g, replace: (/** @type {string} */ _match, /** @type {string} */ capturedGroup) => { - return `Examples: ${capturedGroup.split(' ').join(', ')}.`; + // Extract each backtick-delimited example and join them. Splitting on ' ' + // instead would break apart examples that contain internal spaces (e.g. an + // array literal like `["/orgs/:slug", "/orgs/:slug/(.*)"]`), inserting a + // spurious comma mid-value. + const examples = capturedGroup.match(/`[^`]+`/g) ?? []; + return `Examples: ${examples.join(', ')}.`; }, }, ]; From 180647d5fab6be454d93b4352d506bbfa566049c Mon Sep 17 00:00:00 2001 From: Sarah Soutoul Date: Tue, 21 Jul 2026 16:09:09 +0200 Subject: [PATCH 2/4] docs(repo): make typedoc comma fix changeset empty The fix only touches the generated-docs tooling (.typedoc/custom-plugin.mjs), not @clerk/backend runtime code, so it shouldn't trigger a package version bump. --- .changeset/typedoc-multi-example-double-comma.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/.changeset/typedoc-multi-example-double-comma.md b/.changeset/typedoc-multi-example-double-comma.md index cf3413af303..a845151cc84 100644 --- a/.changeset/typedoc-multi-example-double-comma.md +++ b/.changeset/typedoc-multi-example-double-comma.md @@ -1,5 +1,2 @@ --- -'@clerk/backend': patch --- - -Fix the Typedoc generator inserting a spurious extra comma inside multi-`@example` values. The "Examples" replacement split the captured group on every space, which broke apart example values containing internal spaces (e.g. array literals like `["/orgs/:slug", "/orgs/:slug/(.*)"]`) and rejoined them with `, `, producing `,,`. It now joins the backtick-delimited examples directly. Generated-output-only change; no runtime behavior is affected. From f323fc935052a1bd2d1c55b3600e7ec92a78031c Mon Sep 17 00:00:00 2001 From: Michael Novotny Date: Tue, 21 Jul 2026 10:17:36 -0500 Subject: [PATCH 3/4] docs(repo): condense multi-example replacement comment Co-Authored-By: Claude Fable 5 --- .typedoc/custom-plugin.mjs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.typedoc/custom-plugin.mjs b/.typedoc/custom-plugin.mjs index 854ef6f154d..3b56bb739de 100644 --- a/.typedoc/custom-plugin.mjs +++ b/.typedoc/custom-plugin.mjs @@ -395,10 +395,7 @@ function getCatchAllReplacements() { */ pattern: /\*\*Examples\*\* ((?:`[^`]+`)(?: `[^`]+`)*)/g, replace: (/** @type {string} */ _match, /** @type {string} */ capturedGroup) => { - // Extract each backtick-delimited example and join them. Splitting on ' ' - // instead would break apart examples that contain internal spaces (e.g. an - // array literal like `["/orgs/:slug", "/orgs/:slug/(.*)"]`), inserting a - // spurious comma mid-value. + // Match backtick-delimited examples individually; splitting on ' ' breaks examples with internal spaces. const examples = capturedGroup.match(/`[^`]+`/g) ?? []; return `Examples: ${examples.join(', ')}.`; }, From d4576d1565599bc730be095a17cae7201904c03d Mon Sep 17 00:00:00 2001 From: Sarah Soutoul Date: Tue, 21 Jul 2026 17:35:12 +0200 Subject: [PATCH 4/4] ci: retrigger checks Co-Authored-By: Claude Sonnet 5