Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/fix-lock-user-doc-link.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
---
'@clerk/backend': patch
---

Update the `lockUser()` documentation to link to the current Rules page in the Clerk Dashboard.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
Removes the password credential from the given user. This is a privileged operation and does not require the user's current password. Password removal is allowed even when the user has no other sign-in method configured.

By default, existing sessions remain active. Set `signOutOfOtherSessions` to `true` to revoke sessions active when the request is processed.

Returns the updated [`User`](/docs/reference/backend/types/backend-user).

```typescript
function removePassword(userId: string, params: { signOutOfOtherSessions?: boolean }): Promise<User>

@coderabbitaicoderabbitaiBotAug 10, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bashset -euo pipefail
source_file='packages/backend/src/api/endpoints/UserApi.ts'
snapshot_file='.typedoc/__tests__/__snapshots__/user-api-methods-remove-password.mdx'
rg -n -A3 -B2 'removePassword'"$source_file"
rg -n 'function removePassword'"$snapshot_file"if rg -q 'function removePassword\(userId: string, params: '"$snapshot_file"&&! rg -q 'function removePassword\(userId: string, params\?: '"$snapshot_file";thenecho'Generated signature marks params as required.'exit 1
fi

Repository: clerk/javascript

Length of output: 797


🏁 Script executed:

set -euo pipefail
printf'%s\n''--- TypeDoc configuration and custom rendering references ---'
rg -n -S -i 'typedoc|signature.*render|default.*param|optional.*param|RemovePasswordParams' \
.typedoc packages package.json pnpm-workspace.yaml 2>/dev/null | head -n 240
printf'%s\n''--- Relevant snapshot and source context ---'
sed -n '1,24p' .typedoc/__tests__/__snapshots__/user-api-methods-remove-password.mdx
sed -n '700,742p' packages/backend/src/api/endpoints/UserApi.ts
printf'%s\n''--- Tests and scripts that generate or validate TypeDoc snapshots ---'
rg -n -S 'typedoc|user-api-methods-remove-password|__snapshots__' \
.github package.json .typedoc packages 2>/dev/null | head -n 240

Repository: clerk/javascript

Length of output: 50374


🏁 Script executed:

set -euo pipefail
printf'%s\n''--- Signature rendering implementation ---'
sed -n '1220,1435p' .typedoc/custom-theme.mjs
printf'%s\n''--- Optional-parameter helper implementation ---'
sed -n '420,455p' .typedoc/custom-theme.mjs
sed -n '560,605p' .typedoc/custom-theme.mjs
printf'%s\n''--- TypeDoc configuration ---'
sed -n '1,220p' typedoc.config.mjs

Repository: clerk/javascript

Length of output: 15853


🏁 Script executed:

set -euo pipefail
printf'%s\n''--- Signature-parameter hooks and custom partials ---'
rg -n -C 12 'signatureParameters|signatureParameter|isOptional|defaultValue' .typedoc/custom-theme.mjs | head -n 260
printf'%s\n''--- TypeDoc model fixtures or generated metadata for removePassword ---'
rg -n -S -C 8 'removePassword|RemovePasswordParams' .typedoc packages/backend/src/api/__tests__ packages/backend/src/api/endpoints | head -n 220
printf'%s\n''--- Comparable default-parameter signatures in snapshots ---'
rg -n -S 'function .*\([^)]*=|function .*\([^)]*\?:' .typedoc/__tests__/__snapshots__ | head -n 160

Repository: clerk/javascript

Length of output: 23999


🏁 Script executed:

set -euo pipefail
python3 - <<'PY'from pathlib import Pathimport resource = Path("packages/backend/src/api/endpoints/UserApi.ts").read_text()snapshot = Path(".typedoc/__tests__/__snapshots__/user-api-methods-remove-password.mdx").read_text()comparables = { p.name: p.read_text() for p in Path(".typedoc/__tests__/__snapshots__").glob("*.mdx")}method = re.search( r"public async removePassword\(\s*userId:\s*string,\s*params:\s*RemovePasswordParams\s*=\s*\{\}\s*\)", source,)rendered = re.search( r"function removePassword\(userId: string, params(\?)?: \{ signOutOfOtherSessions\?: boolean \}\)", snapshot,)assert method, "removePassword source declaration was not found"assert rendered, "removePassword snapshot signature was not found"print("source_default_parameter:", True)print("snapshot_params_optional:", rendered.group(1) == "?")print("snapshot_signature:", rendered.group(0))for name, text in comparables.items(): if re.search(r"function (?:signOut|sendCode)\([^)]*\?:", text): print("comparable_optional_signature:", name)PY

Repository: clerk/javascript

Length of output: 469


Render params as optional.

removePassword provides a default value for params, but the generated signature marks it as required. Update the TypeDoc signature rendering and regenerate the snapshot.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.typedoc/__tests__/__snapshots__/user-api-methods-remove-password.mdx at
line 8, Update the TypeDoc signature rendering for removePassword so its
defaulted params argument is rendered as optional, then regenerate the
user-api-methods-remove-password snapshot to reflect the corrected signature.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Skipping this one. It's semantically right — params has a = {} default, so TS declaration output would render it as params? — but the missing ? comes from formatTypeScriptSignature(), which this PR doesn't touch. The snapshot has to mirror generated output, so patching just the snapshot would make the test lie. A real fix means teaching the formatter to detect default-initialized params and regenerating every affected snapshot, which is out of scope here.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@manovotny, agreed. The snapshot must reflect the current formatter output. A snapshot-only change would be incorrect.

This finding is out of scope for this PR. A separate fix should update formatTypeScriptSignature() and regenerate all affected snapshots.

Would you like me to open a follow-up issue for that work?


✏️ Learnings added
Learnt from: manovotny
Repo: clerk/javascript PR: 9372
File: .typedoc/__tests__/__snapshots__/user-api-methods-remove-password.mdx:8-8
Timestamp: 2026-08-10T18:13:38.851Z
Learning: In the `.typedoc` documentation generator, `.typedoc/formatTypeScriptSignature()` controls parameter optionality in generated TypeScript signatures. Snapshots must mirror formatter output. Correctly rendering default-initialized parameters such as `params: RemovePasswordParams = {}` as optional requires a formatter change and regeneration of all affected snapshots.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

You are interacting with an AI system.

```

## Parameters


| Parameter | Type | Description |
| ------ | ------ | ------ |
| `userId` | `string` | The ID of the user whose password to remove. |
| `params` | <code>\{ signOutOfOtherSessions?: boolean; \}</code> | Options for the request. |
| `params.signOutOfOtherSessions?` | `boolean` | When set to `true`, all of the user's active sessions are revoked after their password is removed. Defaults to `false`. |
6 changes: 6 additions & 0 deletions .typedoc/__tests__/extract-methods.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -18,6 +18,7 @@ import { describe, expect, it } from 'vitest';
* - `methods/check-authorization.mdx` – generic instantiation (`CheckAuthorization`)
* - `methods/email-code-send-code.mdx` – qualified name from `@extractMethods` parent
* - `methods/email-link.mdx` – `@extractMethods` namespace index (non-callables)
* - `methods/remove-password.mdx` – backend page format with omitted `@example` blocks
* - `properties.mdx` (clerk) – properties table sliced from already-prettified page
* - `clerk.mdx` – main page after Properties has been stripped
* - `properties.mdx` (user-resource) – properties with external type links and metadata
Expand DownExpand Up@@ -71,6 +72,11 @@ describe('extract-methods snapshots', () => {
await expect(content).toMatchFileSnapshot('./__snapshots__/sign-in-future-resource-methods-email-link.mdx');
});

it('backend page format omits examples: users.removePassword()', async () => {
const content = await readGenerated('backend/user-api/methods/remove-password.mdx');
await expect(content).toMatchFileSnapshot('./__snapshots__/user-api-methods-remove-password.mdx');
});

it('properties extracted + prettier-aligned: clerk', async () => {
const content = await readGenerated('shared/clerk/properties.mdx');
await expect(content).toMatchFileSnapshot('./__snapshots__/clerk-properties.mdx');
Expand Down
10 changes: 7 additions & 3 deletions .typedoc/extract-methods.mjs
Original file line numberDiff line numberDiff line change
Expand Up@@ -729,15 +729,19 @@ const BLOCK_TAGS_OMITTED_FROM_EXTRACTED_METHOD_PROSE = new Set(['@param', '@type

/**
* @param {import('typedoc').Comment | undefined} comment
* @param {{ omitExamples?: boolean }} [options]
*/
function commentSummaryAndBody(comment) {
function commentSummaryAndBody(comment, options = {}) {
if (!comment) {
return '';
}
const c = applyTodoStrippingToComment(comment) ?? comment;
const summary = displayPartsToString(c.summary).trim();
const block = c.blockTags
?.filter(t => !BLOCK_TAGS_OMITTED_FROM_EXTRACTED_METHOD_PROSE.has(t.tag))
?.filter(
t =>
!BLOCK_TAGS_OMITTED_FROM_EXTRACTED_METHOD_PROSE.has(t.tag) && !(options.omitExamples && t.tag === '@example'),
)
.map(t => displayPartsToString(t.content).trim())
.filter(Boolean)
.join('\n\n');
Expand DownExpand Up@@ -1233,7 +1237,7 @@ function buildMethodMdx(decl, ctx, options = {}) {
const paramsHeadingLevel = methodFormat === 'page' ? 2 : 4;
/** Prefer the declaration comment (property-style methods document `addListener` on the property, not the signature). */
const comment = decl.comment ?? sig.comment;
let description = commentSummaryAndBody(comment);
let description = commentSummaryAndBody(comment, { omitExamples: methodFormat === 'page' });
const sigReturns = comment === sig.comment ? '' : appendSignatureOnlyReturns(decl.comment, sig.comment);
if (sigReturns) {
description = [description, sigReturns].filter(Boolean).join('\n\n');
Expand Down
2 changes: 1 addition & 1 deletion packages/backend/src/api/endpoints/UserApi.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -785,7 +785,7 @@ export class UserAPI extends AbstractAPI {
}

/**
* Locks the given [`User`](https://clerk.com/docs/reference/backend/types/backend-user), which means that they are not allowed to sign in again until the lock expires or is manually unlocked. By default, lockout duration is 1 hour, but it can be configured in the application's [**Attack protection**](https://dashboard.clerk.com/~/protect/attack-protection) settings. See the [guide on user locks](https://clerk.com/docs/guides/secure/user-lockout).
* Locks the given [`User`](https://clerk.com/docs/reference/backend/types/backend-user), which means that they are not allowed to sign in again until the lock expires or is manually unlocked. By default, lockout duration is 1 hour, but it can be configured in the application's [**Rules**](https://dashboard.clerk.com/~/protect/rules) settings. See the [guide on user locks](https://clerk.com/docs/guides/secure/user-lockout).
* @param userId - The ID of the user to lock.
*/
public async lockUser(userId: string) {
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
docs(backend): fix Dashboard links and method reference layout by SarahSoutoul · Pull Request #9372 · clerk/javascript · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/fix-lock-user-doc-link.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
---
'@clerk/backend': patch
---

Update the `lockUser()` documentation to link to the current Rules page in the Clerk Dashboard.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
Removes the password credential from the given user. This is a privileged operation and does not require the user's current password. Password removal is allowed even when the user has no other sign-in method configured.

By default, existing sessions remain active. Set `signOutOfOtherSessions` to `true` to revoke sessions active when the request is processed.

Returns the updated [`User`](/docs/reference/backend/types/backend-user).

```typescript
function removePassword(userId: string, params: { signOutOfOtherSessions?: boolean }): Promise<User>

@coderabbitaicoderabbitaiBotAug 10, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bashset -euo pipefail
source_file='packages/backend/src/api/endpoints/UserApi.ts'
snapshot_file='.typedoc/__tests__/__snapshots__/user-api-methods-remove-password.mdx'
rg -n -A3 -B2 'removePassword'"$source_file"
rg -n 'function removePassword'"$snapshot_file"if rg -q 'function removePassword\(userId: string, params: '"$snapshot_file"&&! rg -q 'function removePassword\(userId: string, params\?: '"$snapshot_file";thenecho'Generated signature marks params as required.'exit 1
fi

Repository: clerk/javascript

Length of output: 797


🏁 Script executed:

set -euo pipefail
printf'%s\n''--- TypeDoc configuration and custom rendering references ---'
rg -n -S -i 'typedoc|signature.*render|default.*param|optional.*param|RemovePasswordParams' \
.typedoc packages package.json pnpm-workspace.yaml 2>/dev/null | head -n 240
printf'%s\n''--- Relevant snapshot and source context ---'
sed -n '1,24p' .typedoc/__tests__/__snapshots__/user-api-methods-remove-password.mdx
sed -n '700,742p' packages/backend/src/api/endpoints/UserApi.ts
printf'%s\n''--- Tests and scripts that generate or validate TypeDoc snapshots ---'
rg -n -S 'typedoc|user-api-methods-remove-password|__snapshots__' \
.github package.json .typedoc packages 2>/dev/null | head -n 240

Repository: clerk/javascript

Length of output: 50374


🏁 Script executed:

set -euo pipefail
printf'%s\n''--- Signature rendering implementation ---'
sed -n '1220,1435p' .typedoc/custom-theme.mjs
printf'%s\n''--- Optional-parameter helper implementation ---'
sed -n '420,455p' .typedoc/custom-theme.mjs
sed -n '560,605p' .typedoc/custom-theme.mjs
printf'%s\n''--- TypeDoc configuration ---'
sed -n '1,220p' typedoc.config.mjs

Repository: clerk/javascript

Length of output: 15853


🏁 Script executed:

set -euo pipefail
printf'%s\n''--- Signature-parameter hooks and custom partials ---'
rg -n -C 12 'signatureParameters|signatureParameter|isOptional|defaultValue' .typedoc/custom-theme.mjs | head -n 260
printf'%s\n''--- TypeDoc model fixtures or generated metadata for removePassword ---'
rg -n -S -C 8 'removePassword|RemovePasswordParams' .typedoc packages/backend/src/api/__tests__ packages/backend/src/api/endpoints | head -n 220
printf'%s\n''--- Comparable default-parameter signatures in snapshots ---'
rg -n -S 'function .*\([^)]*=|function .*\([^)]*\?:' .typedoc/__tests__/__snapshots__ | head -n 160

Repository: clerk/javascript

Length of output: 23999


🏁 Script executed:

set -euo pipefail
python3 - <<'PY'from pathlib import Pathimport resource = Path("packages/backend/src/api/endpoints/UserApi.ts").read_text()snapshot = Path(".typedoc/__tests__/__snapshots__/user-api-methods-remove-password.mdx").read_text()comparables = { p.name: p.read_text() for p in Path(".typedoc/__tests__/__snapshots__").glob("*.mdx")}method = re.search( r"public async removePassword\(\s*userId:\s*string,\s*params:\s*RemovePasswordParams\s*=\s*\{\}\s*\)", source,)rendered = re.search( r"function removePassword\(userId: string, params(\?)?: \{ signOutOfOtherSessions\?: boolean \}\)", snapshot,)assert method, "removePassword source declaration was not found"assert rendered, "removePassword snapshot signature was not found"print("source_default_parameter:", True)print("snapshot_params_optional:", rendered.group(1) == "?")print("snapshot_signature:", rendered.group(0))for name, text in comparables.items(): if re.search(r"function (?:signOut|sendCode)\([^)]*\?:", text): print("comparable_optional_signature:", name)PY

Repository: clerk/javascript

Length of output: 469


Render params as optional.

removePassword provides a default value for params, but the generated signature marks it as required. Update the TypeDoc signature rendering and regenerate the snapshot.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.typedoc/__tests__/__snapshots__/user-api-methods-remove-password.mdx at
line 8, Update the TypeDoc signature rendering for removePassword so its
defaulted params argument is rendered as optional, then regenerate the
user-api-methods-remove-password snapshot to reflect the corrected signature.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Skipping this one. It's semantically right — params has a = {} default, so TS declaration output would render it as params? — but the missing ? comes from formatTypeScriptSignature(), which this PR doesn't touch. The snapshot has to mirror generated output, so patching just the snapshot would make the test lie. A real fix means teaching the formatter to detect default-initialized params and regenerating every affected snapshot, which is out of scope here.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@manovotny, agreed. The snapshot must reflect the current formatter output. A snapshot-only change would be incorrect.

This finding is out of scope for this PR. A separate fix should update formatTypeScriptSignature() and regenerate all affected snapshots.

Would you like me to open a follow-up issue for that work?


✏️ Learnings added
Learnt from: manovotny
Repo: clerk/javascript PR: 9372
File: .typedoc/__tests__/__snapshots__/user-api-methods-remove-password.mdx:8-8
Timestamp: 2026-08-10T18:13:38.851Z
Learning: In the `.typedoc` documentation generator, `.typedoc/formatTypeScriptSignature()` controls parameter optionality in generated TypeScript signatures. Snapshots must mirror formatter output. Correctly rendering default-initialized parameters such as `params: RemovePasswordParams = {}` as optional requires a formatter change and regeneration of all affected snapshots.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

You are interacting with an AI system.

```

## Parameters


| Parameter | Type | Description |
| ------ | ------ | ------ |
| `userId` | `string` | The ID of the user whose password to remove. |
| `params` | <code>\{ signOutOfOtherSessions?: boolean; \}</code> | Options for the request. |
| `params.signOutOfOtherSessions?` | `boolean` | When set to `true`, all of the user's active sessions are revoked after their password is removed. Defaults to `false`. |
6 changes: 6 additions & 0 deletions .typedoc/__tests__/extract-methods.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -18,6 +18,7 @@ import { describe, expect, it } from 'vitest';
* - `methods/check-authorization.mdx` – generic instantiation (`CheckAuthorization`)
* - `methods/email-code-send-code.mdx` – qualified name from `@extractMethods` parent
* - `methods/email-link.mdx` – `@extractMethods` namespace index (non-callables)
* - `methods/remove-password.mdx` – backend page format with omitted `@example` blocks
* - `properties.mdx` (clerk) – properties table sliced from already-prettified page
* - `clerk.mdx` – main page after Properties has been stripped
* - `properties.mdx` (user-resource) – properties with external type links and metadata
Expand DownExpand Up@@ -71,6 +72,11 @@ describe('extract-methods snapshots', () => {
await expect(content).toMatchFileSnapshot('./__snapshots__/sign-in-future-resource-methods-email-link.mdx');
});

it('backend page format omits examples: users.removePassword()', async () => {
const content = await readGenerated('backend/user-api/methods/remove-password.mdx');
await expect(content).toMatchFileSnapshot('./__snapshots__/user-api-methods-remove-password.mdx');
});

it('properties extracted + prettier-aligned: clerk', async () => {
const content = await readGenerated('shared/clerk/properties.mdx');
await expect(content).toMatchFileSnapshot('./__snapshots__/clerk-properties.mdx');
Expand Down
10 changes: 7 additions & 3 deletions .typedoc/extract-methods.mjs
Original file line numberDiff line numberDiff line change
Expand Up@@ -729,15 +729,19 @@ const BLOCK_TAGS_OMITTED_FROM_EXTRACTED_METHOD_PROSE = new Set(['@param', '@type

/**
* @param {import('typedoc').Comment | undefined} comment
* @param {{ omitExamples?: boolean }} [options]
*/
function commentSummaryAndBody(comment) {
function commentSummaryAndBody(comment, options = {}) {
if (!comment) {
return '';
}
const c = applyTodoStrippingToComment(comment) ?? comment;
const summary = displayPartsToString(c.summary).trim();
const block = c.blockTags
?.filter(t => !BLOCK_TAGS_OMITTED_FROM_EXTRACTED_METHOD_PROSE.has(t.tag))
?.filter(
t =>
!BLOCK_TAGS_OMITTED_FROM_EXTRACTED_METHOD_PROSE.has(t.tag) && !(options.omitExamples && t.tag === '@example'),
)
.map(t => displayPartsToString(t.content).trim())
.filter(Boolean)
.join('\n\n');
Expand DownExpand Up@@ -1233,7 +1237,7 @@ function buildMethodMdx(decl, ctx, options = {}) {
const paramsHeadingLevel = methodFormat === 'page' ? 2 : 4;
/** Prefer the declaration comment (property-style methods document `addListener` on the property, not the signature). */
const comment = decl.comment ?? sig.comment;
let description = commentSummaryAndBody(comment);
let description = commentSummaryAndBody(comment, { omitExamples: methodFormat === 'page' });
const sigReturns = comment === sig.comment ? '' : appendSignatureOnlyReturns(decl.comment, sig.comment);
if (sigReturns) {
description = [description, sigReturns].filter(Boolean).join('\n\n');
Expand Down
2 changes: 1 addition & 1 deletion packages/backend/src/api/endpoints/UserApi.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -785,7 +785,7 @@ export class UserAPI extends AbstractAPI {
}

/**
* Locks the given [`User`](https://clerk.com/docs/reference/backend/types/backend-user), which means that they are not allowed to sign in again until the lock expires or is manually unlocked. By default, lockout duration is 1 hour, but it can be configured in the application's [**Attack protection**](https://dashboard.clerk.com/~/protect/attack-protection) settings. See the [guide on user locks](https://clerk.com/docs/guides/secure/user-lockout).
* Locks the given [`User`](https://clerk.com/docs/reference/backend/types/backend-user), which means that they are not allowed to sign in again until the lock expires or is manually unlocked. By default, lockout duration is 1 hour, but it can be configured in the application's [**Rules**](https://dashboard.clerk.com/~/protect/rules) settings. See the [guide on user locks](https://clerk.com/docs/guides/secure/user-lockout).
* @param userId - The ID of the user to lock.
*/
public async lockUser(userId: string) {
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' docs(backend): fix Dashboard links and method reference layout by SarahSoutoul · Pull Request #9372 · clerk/javascript · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/fix-lock-user-doc-link.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
---
'@clerk/backend': patch
---

Update the `lockUser()` documentation to link to the current Rules page in the Clerk Dashboard.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
Removes the password credential from the given user. This is a privileged operation and does not require the user's current password. Password removal is allowed even when the user has no other sign-in method configured.

By default, existing sessions remain active. Set `signOutOfOtherSessions` to `true` to revoke sessions active when the request is processed.

Returns the updated [`User`](/docs/reference/backend/types/backend-user).

```typescript
function removePassword(userId: string, params: { signOutOfOtherSessions?: boolean }): Promise<User>

@coderabbitaicoderabbitaiBotAug 10, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bashset -euo pipefail
source_file='packages/backend/src/api/endpoints/UserApi.ts'
snapshot_file='.typedoc/__tests__/__snapshots__/user-api-methods-remove-password.mdx'
rg -n -A3 -B2 'removePassword'"$source_file"
rg -n 'function removePassword'"$snapshot_file"if rg -q 'function removePassword\(userId: string, params: '"$snapshot_file"&&! rg -q 'function removePassword\(userId: string, params\?: '"$snapshot_file";thenecho'Generated signature marks params as required.'exit 1
fi

Repository: clerk/javascript

Length of output: 797


🏁 Script executed:

set -euo pipefail
printf'%s\n''--- TypeDoc configuration and custom rendering references ---'
rg -n -S -i 'typedoc|signature.*render|default.*param|optional.*param|RemovePasswordParams' \
.typedoc packages package.json pnpm-workspace.yaml 2>/dev/null | head -n 240
printf'%s\n''--- Relevant snapshot and source context ---'
sed -n '1,24p' .typedoc/__tests__/__snapshots__/user-api-methods-remove-password.mdx
sed -n '700,742p' packages/backend/src/api/endpoints/UserApi.ts
printf'%s\n''--- Tests and scripts that generate or validate TypeDoc snapshots ---'
rg -n -S 'typedoc|user-api-methods-remove-password|__snapshots__' \
.github package.json .typedoc packages 2>/dev/null | head -n 240

Repository: clerk/javascript

Length of output: 50374


🏁 Script executed:

set -euo pipefail
printf'%s\n''--- Signature rendering implementation ---'
sed -n '1220,1435p' .typedoc/custom-theme.mjs
printf'%s\n''--- Optional-parameter helper implementation ---'
sed -n '420,455p' .typedoc/custom-theme.mjs
sed -n '560,605p' .typedoc/custom-theme.mjs
printf'%s\n''--- TypeDoc configuration ---'
sed -n '1,220p' typedoc.config.mjs

Repository: clerk/javascript

Length of output: 15853


🏁 Script executed:

set -euo pipefail
printf'%s\n''--- Signature-parameter hooks and custom partials ---'
rg -n -C 12 'signatureParameters|signatureParameter|isOptional|defaultValue' .typedoc/custom-theme.mjs | head -n 260
printf'%s\n''--- TypeDoc model fixtures or generated metadata for removePassword ---'
rg -n -S -C 8 'removePassword|RemovePasswordParams' .typedoc packages/backend/src/api/__tests__ packages/backend/src/api/endpoints | head -n 220
printf'%s\n''--- Comparable default-parameter signatures in snapshots ---'
rg -n -S 'function .*\([^)]*=|function .*\([^)]*\?:' .typedoc/__tests__/__snapshots__ | head -n 160

Repository: clerk/javascript

Length of output: 23999


🏁 Script executed:

set -euo pipefail
python3 - <<'PY'from pathlib import Pathimport resource = Path("packages/backend/src/api/endpoints/UserApi.ts").read_text()snapshot = Path(".typedoc/__tests__/__snapshots__/user-api-methods-remove-password.mdx").read_text()comparables = { p.name: p.read_text() for p in Path(".typedoc/__tests__/__snapshots__").glob("*.mdx")}method = re.search( r"public async removePassword\(\s*userId:\s*string,\s*params:\s*RemovePasswordParams\s*=\s*\{\}\s*\)", source,)rendered = re.search( r"function removePassword\(userId: string, params(\?)?: \{ signOutOfOtherSessions\?: boolean \}\)", snapshot,)assert method, "removePassword source declaration was not found"assert rendered, "removePassword snapshot signature was not found"print("source_default_parameter:", True)print("snapshot_params_optional:", rendered.group(1) == "?")print("snapshot_signature:", rendered.group(0))for name, text in comparables.items(): if re.search(r"function (?:signOut|sendCode)\([^)]*\?:", text): print("comparable_optional_signature:", name)PY

Repository: clerk/javascript

Length of output: 469


Render params as optional.

removePassword provides a default value for params, but the generated signature marks it as required. Update the TypeDoc signature rendering and regenerate the snapshot.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.typedoc/__tests__/__snapshots__/user-api-methods-remove-password.mdx at
line 8, Update the TypeDoc signature rendering for removePassword so its
defaulted params argument is rendered as optional, then regenerate the
user-api-methods-remove-password snapshot to reflect the corrected signature.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Skipping this one. It's semantically right — params has a = {} default, so TS declaration output would render it as params? — but the missing ? comes from formatTypeScriptSignature(), which this PR doesn't touch. The snapshot has to mirror generated output, so patching just the snapshot would make the test lie. A real fix means teaching the formatter to detect default-initialized params and regenerating every affected snapshot, which is out of scope here.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@manovotny, agreed. The snapshot must reflect the current formatter output. A snapshot-only change would be incorrect.

This finding is out of scope for this PR. A separate fix should update formatTypeScriptSignature() and regenerate all affected snapshots.

Would you like me to open a follow-up issue for that work?


✏️ Learnings added
Learnt from: manovotny
Repo: clerk/javascript PR: 9372
File: .typedoc/__tests__/__snapshots__/user-api-methods-remove-password.mdx:8-8
Timestamp: 2026-08-10T18:13:38.851Z
Learning: In the `.typedoc` documentation generator, `.typedoc/formatTypeScriptSignature()` controls parameter optionality in generated TypeScript signatures. Snapshots must mirror formatter output. Correctly rendering default-initialized parameters such as `params: RemovePasswordParams = {}` as optional requires a formatter change and regeneration of all affected snapshots.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

You are interacting with an AI system.

```

## Parameters


| Parameter | Type | Description |
| ------ | ------ | ------ |
| `userId` | `string` | The ID of the user whose password to remove. |
| `params` | <code>\{ signOutOfOtherSessions?: boolean; \}</code> | Options for the request. |
| `params.signOutOfOtherSessions?` | `boolean` | When set to `true`, all of the user's active sessions are revoked after their password is removed. Defaults to `false`. |
6 changes: 6 additions & 0 deletions .typedoc/__tests__/extract-methods.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -18,6 +18,7 @@ import { describe, expect, it } from 'vitest';
* - `methods/check-authorization.mdx` – generic instantiation (`CheckAuthorization`)
* - `methods/email-code-send-code.mdx` – qualified name from `@extractMethods` parent
* - `methods/email-link.mdx` – `@extractMethods` namespace index (non-callables)
* - `methods/remove-password.mdx` – backend page format with omitted `@example` blocks
* - `properties.mdx` (clerk) – properties table sliced from already-prettified page
* - `clerk.mdx` – main page after Properties has been stripped
* - `properties.mdx` (user-resource) – properties with external type links and metadata
Expand DownExpand Up@@ -71,6 +72,11 @@ describe('extract-methods snapshots', () => {
await expect(content).toMatchFileSnapshot('./__snapshots__/sign-in-future-resource-methods-email-link.mdx');
});

it('backend page format omits examples: users.removePassword()', async () => {
const content = await readGenerated('backend/user-api/methods/remove-password.mdx');
await expect(content).toMatchFileSnapshot('./__snapshots__/user-api-methods-remove-password.mdx');
});

it('properties extracted + prettier-aligned: clerk', async () => {
const content = await readGenerated('shared/clerk/properties.mdx');
await expect(content).toMatchFileSnapshot('./__snapshots__/clerk-properties.mdx');
Expand Down
10 changes: 7 additions & 3 deletions .typedoc/extract-methods.mjs
Original file line numberDiff line numberDiff line change
Expand Up@@ -729,15 +729,19 @@ const BLOCK_TAGS_OMITTED_FROM_EXTRACTED_METHOD_PROSE = new Set(['@param', '@type

/**
* @param {import('typedoc').Comment | undefined} comment
* @param {{ omitExamples?: boolean }} [options]
*/
function commentSummaryAndBody(comment) {
function commentSummaryAndBody(comment, options = {}) {
if (!comment) {
return '';
}
const c = applyTodoStrippingToComment(comment) ?? comment;
const summary = displayPartsToString(c.summary).trim();
const block = c.blockTags
?.filter(t => !BLOCK_TAGS_OMITTED_FROM_EXTRACTED_METHOD_PROSE.has(t.tag))
?.filter(
t =>
!BLOCK_TAGS_OMITTED_FROM_EXTRACTED_METHOD_PROSE.has(t.tag) && !(options.omitExamples && t.tag === '@example'),
)
.map(t => displayPartsToString(t.content).trim())
.filter(Boolean)
.join('\n\n');
Expand DownExpand Up@@ -1233,7 +1237,7 @@ function buildMethodMdx(decl, ctx, options = {}) {
const paramsHeadingLevel = methodFormat === 'page' ? 2 : 4;
/** Prefer the declaration comment (property-style methods document `addListener` on the property, not the signature). */
const comment = decl.comment ?? sig.comment;
let description = commentSummaryAndBody(comment);
let description = commentSummaryAndBody(comment, { omitExamples: methodFormat === 'page' });
const sigReturns = comment === sig.comment ? '' : appendSignatureOnlyReturns(decl.comment, sig.comment);
if (sigReturns) {
description = [description, sigReturns].filter(Boolean).join('\n\n');
Expand Down
2 changes: 1 addition & 1 deletion packages/backend/src/api/endpoints/UserApi.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -785,7 +785,7 @@ export class UserAPI extends AbstractAPI {
}

/**
* Locks the given [`User`](https://clerk.com/docs/reference/backend/types/backend-user), which means that they are not allowed to sign in again until the lock expires or is manually unlocked. By default, lockout duration is 1 hour, but it can be configured in the application's [**Attack protection**](https://dashboard.clerk.com/~/protect/attack-protection) settings. See the [guide on user locks](https://clerk.com/docs/guides/secure/user-lockout).
* Locks the given [`User`](https://clerk.com/docs/reference/backend/types/backend-user), which means that they are not allowed to sign in again until the lock expires or is manually unlocked. By default, lockout duration is 1 hour, but it can be configured in the application's [**Rules**](https://dashboard.clerk.com/~/protect/rules) settings. See the [guide on user locks](https://clerk.com/docs/guides/secure/user-lockout).
* @param userId - The ID of the user to lock.
*/
public async lockUser(userId: string) {
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' docs(backend): fix Dashboard links and method reference layout by SarahSoutoul · Pull Request #9372 · clerk/javascript · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/fix-lock-user-doc-link.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
---
'@clerk/backend': patch
---

Update the `lockUser()` documentation to link to the current Rules page in the Clerk Dashboard.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
Removes the password credential from the given user. This is a privileged operation and does not require the user's current password. Password removal is allowed even when the user has no other sign-in method configured.

By default, existing sessions remain active. Set `signOutOfOtherSessions` to `true` to revoke sessions active when the request is processed.

Returns the updated [`User`](/docs/reference/backend/types/backend-user).

```typescript
function removePassword(userId: string, params: { signOutOfOtherSessions?: boolean }): Promise<User>

@coderabbitaicoderabbitaiBotAug 10, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bashset -euo pipefail
source_file='packages/backend/src/api/endpoints/UserApi.ts'
snapshot_file='.typedoc/__tests__/__snapshots__/user-api-methods-remove-password.mdx'
rg -n -A3 -B2 'removePassword'"$source_file"
rg -n 'function removePassword'"$snapshot_file"if rg -q 'function removePassword\(userId: string, params: '"$snapshot_file"&&! rg -q 'function removePassword\(userId: string, params\?: '"$snapshot_file";thenecho'Generated signature marks params as required.'exit 1
fi

Repository: clerk/javascript

Length of output: 797


🏁 Script executed:

set -euo pipefail
printf'%s\n''--- TypeDoc configuration and custom rendering references ---'
rg -n -S -i 'typedoc|signature.*render|default.*param|optional.*param|RemovePasswordParams' \
.typedoc packages package.json pnpm-workspace.yaml 2>/dev/null | head -n 240
printf'%s\n''--- Relevant snapshot and source context ---'
sed -n '1,24p' .typedoc/__tests__/__snapshots__/user-api-methods-remove-password.mdx
sed -n '700,742p' packages/backend/src/api/endpoints/UserApi.ts
printf'%s\n''--- Tests and scripts that generate or validate TypeDoc snapshots ---'
rg -n -S 'typedoc|user-api-methods-remove-password|__snapshots__' \
.github package.json .typedoc packages 2>/dev/null | head -n 240

Repository: clerk/javascript

Length of output: 50374


🏁 Script executed:

set -euo pipefail
printf'%s\n''--- Signature rendering implementation ---'
sed -n '1220,1435p' .typedoc/custom-theme.mjs
printf'%s\n''--- Optional-parameter helper implementation ---'
sed -n '420,455p' .typedoc/custom-theme.mjs
sed -n '560,605p' .typedoc/custom-theme.mjs
printf'%s\n''--- TypeDoc configuration ---'
sed -n '1,220p' typedoc.config.mjs

Repository: clerk/javascript

Length of output: 15853


🏁 Script executed:

set -euo pipefail
printf'%s\n''--- Signature-parameter hooks and custom partials ---'
rg -n -C 12 'signatureParameters|signatureParameter|isOptional|defaultValue' .typedoc/custom-theme.mjs | head -n 260
printf'%s\n''--- TypeDoc model fixtures or generated metadata for removePassword ---'
rg -n -S -C 8 'removePassword|RemovePasswordParams' .typedoc packages/backend/src/api/__tests__ packages/backend/src/api/endpoints | head -n 220
printf'%s\n''--- Comparable default-parameter signatures in snapshots ---'
rg -n -S 'function .*\([^)]*=|function .*\([^)]*\?:' .typedoc/__tests__/__snapshots__ | head -n 160

Repository: clerk/javascript

Length of output: 23999


🏁 Script executed:

set -euo pipefail
python3 - <<'PY'from pathlib import Pathimport resource = Path("packages/backend/src/api/endpoints/UserApi.ts").read_text()snapshot = Path(".typedoc/__tests__/__snapshots__/user-api-methods-remove-password.mdx").read_text()comparables = { p.name: p.read_text() for p in Path(".typedoc/__tests__/__snapshots__").glob("*.mdx")}method = re.search( r"public async removePassword\(\s*userId:\s*string,\s*params:\s*RemovePasswordParams\s*=\s*\{\}\s*\)", source,)rendered = re.search( r"function removePassword\(userId: string, params(\?)?: \{ signOutOfOtherSessions\?: boolean \}\)", snapshot,)assert method, "removePassword source declaration was not found"assert rendered, "removePassword snapshot signature was not found"print("source_default_parameter:", True)print("snapshot_params_optional:", rendered.group(1) == "?")print("snapshot_signature:", rendered.group(0))for name, text in comparables.items(): if re.search(r"function (?:signOut|sendCode)\([^)]*\?:", text): print("comparable_optional_signature:", name)PY

Repository: clerk/javascript

Length of output: 469


Render params as optional.

removePassword provides a default value for params, but the generated signature marks it as required. Update the TypeDoc signature rendering and regenerate the snapshot.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.typedoc/__tests__/__snapshots__/user-api-methods-remove-password.mdx at
line 8, Update the TypeDoc signature rendering for removePassword so its
defaulted params argument is rendered as optional, then regenerate the
user-api-methods-remove-password snapshot to reflect the corrected signature.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Skipping this one. It's semantically right — params has a = {} default, so TS declaration output would render it as params? — but the missing ? comes from formatTypeScriptSignature(), which this PR doesn't touch. The snapshot has to mirror generated output, so patching just the snapshot would make the test lie. A real fix means teaching the formatter to detect default-initialized params and regenerating every affected snapshot, which is out of scope here.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@manovotny, agreed. The snapshot must reflect the current formatter output. A snapshot-only change would be incorrect.

This finding is out of scope for this PR. A separate fix should update formatTypeScriptSignature() and regenerate all affected snapshots.

Would you like me to open a follow-up issue for that work?


✏️ Learnings added
Learnt from: manovotny
Repo: clerk/javascript PR: 9372
File: .typedoc/__tests__/__snapshots__/user-api-methods-remove-password.mdx:8-8
Timestamp: 2026-08-10T18:13:38.851Z
Learning: In the `.typedoc` documentation generator, `.typedoc/formatTypeScriptSignature()` controls parameter optionality in generated TypeScript signatures. Snapshots must mirror formatter output. Correctly rendering default-initialized parameters such as `params: RemovePasswordParams = {}` as optional requires a formatter change and regeneration of all affected snapshots.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

You are interacting with an AI system.

```

## Parameters


| Parameter | Type | Description |
| ------ | ------ | ------ |
| `userId` | `string` | The ID of the user whose password to remove. |
| `params` | <code>\{ signOutOfOtherSessions?: boolean; \}</code> | Options for the request. |
| `params.signOutOfOtherSessions?` | `boolean` | When set to `true`, all of the user's active sessions are revoked after their password is removed. Defaults to `false`. |
6 changes: 6 additions & 0 deletions .typedoc/__tests__/extract-methods.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -18,6 +18,7 @@ import { describe, expect, it } from 'vitest';
* - `methods/check-authorization.mdx` – generic instantiation (`CheckAuthorization`)
* - `methods/email-code-send-code.mdx` – qualified name from `@extractMethods` parent
* - `methods/email-link.mdx` – `@extractMethods` namespace index (non-callables)
* - `methods/remove-password.mdx` – backend page format with omitted `@example` blocks
* - `properties.mdx` (clerk) – properties table sliced from already-prettified page
* - `clerk.mdx` – main page after Properties has been stripped
* - `properties.mdx` (user-resource) – properties with external type links and metadata
Expand DownExpand Up@@ -71,6 +72,11 @@ describe('extract-methods snapshots', () => {
await expect(content).toMatchFileSnapshot('./__snapshots__/sign-in-future-resource-methods-email-link.mdx');
});

it('backend page format omits examples: users.removePassword()', async () => {
const content = await readGenerated('backend/user-api/methods/remove-password.mdx');
await expect(content).toMatchFileSnapshot('./__snapshots__/user-api-methods-remove-password.mdx');
});

it('properties extracted + prettier-aligned: clerk', async () => {
const content = await readGenerated('shared/clerk/properties.mdx');
await expect(content).toMatchFileSnapshot('./__snapshots__/clerk-properties.mdx');
Expand Down
10 changes: 7 additions & 3 deletions .typedoc/extract-methods.mjs
Original file line numberDiff line numberDiff line change
Expand Up@@ -729,15 +729,19 @@ const BLOCK_TAGS_OMITTED_FROM_EXTRACTED_METHOD_PROSE = new Set(['@param', '@type

/**
* @param {import('typedoc').Comment | undefined} comment
* @param {{ omitExamples?: boolean }} [options]
*/
function commentSummaryAndBody(comment) {
function commentSummaryAndBody(comment, options = {}) {
if (!comment) {
return '';
}
const c = applyTodoStrippingToComment(comment) ?? comment;
const summary = displayPartsToString(c.summary).trim();
const block = c.blockTags
?.filter(t => !BLOCK_TAGS_OMITTED_FROM_EXTRACTED_METHOD_PROSE.has(t.tag))
?.filter(
t =>
!BLOCK_TAGS_OMITTED_FROM_EXTRACTED_METHOD_PROSE.has(t.tag) && !(options.omitExamples && t.tag === '@example'),
)
.map(t => displayPartsToString(t.content).trim())
.filter(Boolean)
.join('\n\n');
Expand DownExpand Up@@ -1233,7 +1237,7 @@ function buildMethodMdx(decl, ctx, options = {}) {
const paramsHeadingLevel = methodFormat === 'page' ? 2 : 4;
/** Prefer the declaration comment (property-style methods document `addListener` on the property, not the signature). */
const comment = decl.comment ?? sig.comment;
let description = commentSummaryAndBody(comment);
let description = commentSummaryAndBody(comment, { omitExamples: methodFormat === 'page' });
const sigReturns = comment === sig.comment ? '' : appendSignatureOnlyReturns(decl.comment, sig.comment);
if (sigReturns) {
description = [description, sigReturns].filter(Boolean).join('\n\n');
Expand Down
2 changes: 1 addition & 1 deletion packages/backend/src/api/endpoints/UserApi.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -785,7 +785,7 @@ export class UserAPI extends AbstractAPI {
}

/**
* Locks the given [`User`](https://clerk.com/docs/reference/backend/types/backend-user), which means that they are not allowed to sign in again until the lock expires or is manually unlocked. By default, lockout duration is 1 hour, but it can be configured in the application's [**Attack protection**](https://dashboard.clerk.com/~/protect/attack-protection) settings. See the [guide on user locks](https://clerk.com/docs/guides/secure/user-lockout).
* Locks the given [`User`](https://clerk.com/docs/reference/backend/types/backend-user), which means that they are not allowed to sign in again until the lock expires or is manually unlocked. By default, lockout duration is 1 hour, but it can be configured in the application's [**Rules**](https://dashboard.clerk.com/~/protect/rules) settings. See the [guide on user locks](https://clerk.com/docs/guides/secure/user-lockout).
* @param userId - The ID of the user to lock.
*/
public async lockUser(userId: string) {
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' docs(backend): fix Dashboard links and method reference layout by SarahSoutoul · Pull Request #9372 · clerk/javascript · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/fix-lock-user-doc-link.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
---
'@clerk/backend': patch
---

Update the `lockUser()` documentation to link to the current Rules page in the Clerk Dashboard.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
Removes the password credential from the given user. This is a privileged operation and does not require the user's current password. Password removal is allowed even when the user has no other sign-in method configured.

By default, existing sessions remain active. Set `signOutOfOtherSessions` to `true` to revoke sessions active when the request is processed.

Returns the updated [`User`](/docs/reference/backend/types/backend-user).

```typescript
function removePassword(userId: string, params: { signOutOfOtherSessions?: boolean }): Promise<User>

@coderabbitaicoderabbitaiBotAug 10, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bashset -euo pipefail
source_file='packages/backend/src/api/endpoints/UserApi.ts'
snapshot_file='.typedoc/__tests__/__snapshots__/user-api-methods-remove-password.mdx'
rg -n -A3 -B2 'removePassword'"$source_file"
rg -n 'function removePassword'"$snapshot_file"if rg -q 'function removePassword\(userId: string, params: '"$snapshot_file"&&! rg -q 'function removePassword\(userId: string, params\?: '"$snapshot_file";thenecho'Generated signature marks params as required.'exit 1
fi

Repository: clerk/javascript

Length of output: 797


🏁 Script executed:

set -euo pipefail
printf'%s\n''--- TypeDoc configuration and custom rendering references ---'
rg -n -S -i 'typedoc|signature.*render|default.*param|optional.*param|RemovePasswordParams' \
.typedoc packages package.json pnpm-workspace.yaml 2>/dev/null | head -n 240
printf'%s\n''--- Relevant snapshot and source context ---'
sed -n '1,24p' .typedoc/__tests__/__snapshots__/user-api-methods-remove-password.mdx
sed -n '700,742p' packages/backend/src/api/endpoints/UserApi.ts
printf'%s\n''--- Tests and scripts that generate or validate TypeDoc snapshots ---'
rg -n -S 'typedoc|user-api-methods-remove-password|__snapshots__' \
.github package.json .typedoc packages 2>/dev/null | head -n 240

Repository: clerk/javascript

Length of output: 50374


🏁 Script executed:

set -euo pipefail
printf'%s\n''--- Signature rendering implementation ---'
sed -n '1220,1435p' .typedoc/custom-theme.mjs
printf'%s\n''--- Optional-parameter helper implementation ---'
sed -n '420,455p' .typedoc/custom-theme.mjs
sed -n '560,605p' .typedoc/custom-theme.mjs
printf'%s\n''--- TypeDoc configuration ---'
sed -n '1,220p' typedoc.config.mjs

Repository: clerk/javascript

Length of output: 15853


🏁 Script executed:

set -euo pipefail
printf'%s\n''--- Signature-parameter hooks and custom partials ---'
rg -n -C 12 'signatureParameters|signatureParameter|isOptional|defaultValue' .typedoc/custom-theme.mjs | head -n 260
printf'%s\n''--- TypeDoc model fixtures or generated metadata for removePassword ---'
rg -n -S -C 8 'removePassword|RemovePasswordParams' .typedoc packages/backend/src/api/__tests__ packages/backend/src/api/endpoints | head -n 220
printf'%s\n''--- Comparable default-parameter signatures in snapshots ---'
rg -n -S 'function .*\([^)]*=|function .*\([^)]*\?:' .typedoc/__tests__/__snapshots__ | head -n 160

Repository: clerk/javascript

Length of output: 23999


🏁 Script executed:

set -euo pipefail
python3 - <<'PY'from pathlib import Pathimport resource = Path("packages/backend/src/api/endpoints/UserApi.ts").read_text()snapshot = Path(".typedoc/__tests__/__snapshots__/user-api-methods-remove-password.mdx").read_text()comparables = { p.name: p.read_text() for p in Path(".typedoc/__tests__/__snapshots__").glob("*.mdx")}method = re.search( r"public async removePassword\(\s*userId:\s*string,\s*params:\s*RemovePasswordParams\s*=\s*\{\}\s*\)", source,)rendered = re.search( r"function removePassword\(userId: string, params(\?)?: \{ signOutOfOtherSessions\?: boolean \}\)", snapshot,)assert method, "removePassword source declaration was not found"assert rendered, "removePassword snapshot signature was not found"print("source_default_parameter:", True)print("snapshot_params_optional:", rendered.group(1) == "?")print("snapshot_signature:", rendered.group(0))for name, text in comparables.items(): if re.search(r"function (?:signOut|sendCode)\([^)]*\?:", text): print("comparable_optional_signature:", name)PY

Repository: clerk/javascript

Length of output: 469


Render params as optional.

removePassword provides a default value for params, but the generated signature marks it as required. Update the TypeDoc signature rendering and regenerate the snapshot.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.typedoc/__tests__/__snapshots__/user-api-methods-remove-password.mdx at
line 8, Update the TypeDoc signature rendering for removePassword so its
defaulted params argument is rendered as optional, then regenerate the
user-api-methods-remove-password snapshot to reflect the corrected signature.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Skipping this one. It's semantically right — params has a = {} default, so TS declaration output would render it as params? — but the missing ? comes from formatTypeScriptSignature(), which this PR doesn't touch. The snapshot has to mirror generated output, so patching just the snapshot would make the test lie. A real fix means teaching the formatter to detect default-initialized params and regenerating every affected snapshot, which is out of scope here.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@manovotny, agreed. The snapshot must reflect the current formatter output. A snapshot-only change would be incorrect.

This finding is out of scope for this PR. A separate fix should update formatTypeScriptSignature() and regenerate all affected snapshots.

Would you like me to open a follow-up issue for that work?


✏️ Learnings added
Learnt from: manovotny
Repo: clerk/javascript PR: 9372
File: .typedoc/__tests__/__snapshots__/user-api-methods-remove-password.mdx:8-8
Timestamp: 2026-08-10T18:13:38.851Z
Learning: In the `.typedoc` documentation generator, `.typedoc/formatTypeScriptSignature()` controls parameter optionality in generated TypeScript signatures. Snapshots must mirror formatter output. Correctly rendering default-initialized parameters such as `params: RemovePasswordParams = {}` as optional requires a formatter change and regeneration of all affected snapshots.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

You are interacting with an AI system.

```

## Parameters


| Parameter | Type | Description |
| ------ | ------ | ------ |
| `userId` | `string` | The ID of the user whose password to remove. |
| `params` | <code>\{ signOutOfOtherSessions?: boolean; \}</code> | Options for the request. |
| `params.signOutOfOtherSessions?` | `boolean` | When set to `true`, all of the user's active sessions are revoked after their password is removed. Defaults to `false`. |
6 changes: 6 additions & 0 deletions .typedoc/__tests__/extract-methods.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -18,6 +18,7 @@ import { describe, expect, it } from 'vitest';
* - `methods/check-authorization.mdx` – generic instantiation (`CheckAuthorization`)
* - `methods/email-code-send-code.mdx` – qualified name from `@extractMethods` parent
* - `methods/email-link.mdx` – `@extractMethods` namespace index (non-callables)
* - `methods/remove-password.mdx` – backend page format with omitted `@example` blocks
* - `properties.mdx` (clerk) – properties table sliced from already-prettified page
* - `clerk.mdx` – main page after Properties has been stripped
* - `properties.mdx` (user-resource) – properties with external type links and metadata
Expand DownExpand Up@@ -71,6 +72,11 @@ describe('extract-methods snapshots', () => {
await expect(content).toMatchFileSnapshot('./__snapshots__/sign-in-future-resource-methods-email-link.mdx');
});

it('backend page format omits examples: users.removePassword()', async () => {
const content = await readGenerated('backend/user-api/methods/remove-password.mdx');
await expect(content).toMatchFileSnapshot('./__snapshots__/user-api-methods-remove-password.mdx');
});

it('properties extracted + prettier-aligned: clerk', async () => {
const content = await readGenerated('shared/clerk/properties.mdx');
await expect(content).toMatchFileSnapshot('./__snapshots__/clerk-properties.mdx');
Expand Down
10 changes: 7 additions & 3 deletions .typedoc/extract-methods.mjs
Original file line numberDiff line numberDiff line change
Expand Up@@ -729,15 +729,19 @@ const BLOCK_TAGS_OMITTED_FROM_EXTRACTED_METHOD_PROSE = new Set(['@param', '@type

/**
* @param {import('typedoc').Comment | undefined} comment
* @param {{ omitExamples?: boolean }} [options]
*/
function commentSummaryAndBody(comment) {
function commentSummaryAndBody(comment, options = {}) {
if (!comment) {
return '';
}
const c = applyTodoStrippingToComment(comment) ?? comment;
const summary = displayPartsToString(c.summary).trim();
const block = c.blockTags
?.filter(t => !BLOCK_TAGS_OMITTED_FROM_EXTRACTED_METHOD_PROSE.has(t.tag))
?.filter(
t =>
!BLOCK_TAGS_OMITTED_FROM_EXTRACTED_METHOD_PROSE.has(t.tag) && !(options.omitExamples && t.tag === '@example'),
)
.map(t => displayPartsToString(t.content).trim())
.filter(Boolean)
.join('\n\n');
Expand DownExpand Up@@ -1233,7 +1237,7 @@ function buildMethodMdx(decl, ctx, options = {}) {
const paramsHeadingLevel = methodFormat === 'page' ? 2 : 4;
/** Prefer the declaration comment (property-style methods document `addListener` on the property, not the signature). */
const comment = decl.comment ?? sig.comment;
let description = commentSummaryAndBody(comment);
let description = commentSummaryAndBody(comment, { omitExamples: methodFormat === 'page' });
const sigReturns = comment === sig.comment ? '' : appendSignatureOnlyReturns(decl.comment, sig.comment);
if (sigReturns) {
description = [description, sigReturns].filter(Boolean).join('\n\n');
Expand Down
2 changes: 1 addition & 1 deletion packages/backend/src/api/endpoints/UserApi.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -785,7 +785,7 @@ export class UserAPI extends AbstractAPI {
}

/**
* Locks the given [`User`](https://clerk.com/docs/reference/backend/types/backend-user), which means that they are not allowed to sign in again until the lock expires or is manually unlocked. By default, lockout duration is 1 hour, but it can be configured in the application's [**Attack protection**](https://dashboard.clerk.com/~/protect/attack-protection) settings. See the [guide on user locks](https://clerk.com/docs/guides/secure/user-lockout).
* Locks the given [`User`](https://clerk.com/docs/reference/backend/types/backend-user), which means that they are not allowed to sign in again until the lock expires or is manually unlocked. By default, lockout duration is 1 hour, but it can be configured in the application's [**Rules**](https://dashboard.clerk.com/~/protect/rules) settings. See the [guide on user locks](https://clerk.com/docs/guides/secure/user-lockout).
* @param userId - The ID of the user to lock.
*/
public async lockUser(userId: string) {
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' docs(backend): fix Dashboard links and method reference layout by SarahSoutoul · Pull Request #9372 · clerk/javascript · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/fix-lock-user-doc-link.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
---
'@clerk/backend': patch
---

Update the `lockUser()` documentation to link to the current Rules page in the Clerk Dashboard.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
Removes the password credential from the given user. This is a privileged operation and does not require the user's current password. Password removal is allowed even when the user has no other sign-in method configured.

By default, existing sessions remain active. Set `signOutOfOtherSessions` to `true` to revoke sessions active when the request is processed.

Returns the updated [`User`](/docs/reference/backend/types/backend-user).

```typescript
function removePassword(userId: string, params: { signOutOfOtherSessions?: boolean }): Promise<User>

@coderabbitaicoderabbitaiBotAug 10, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bashset -euo pipefail
source_file='packages/backend/src/api/endpoints/UserApi.ts'
snapshot_file='.typedoc/__tests__/__snapshots__/user-api-methods-remove-password.mdx'
rg -n -A3 -B2 'removePassword'"$source_file"
rg -n 'function removePassword'"$snapshot_file"if rg -q 'function removePassword\(userId: string, params: '"$snapshot_file"&&! rg -q 'function removePassword\(userId: string, params\?: '"$snapshot_file";thenecho'Generated signature marks params as required.'exit 1
fi

Repository: clerk/javascript

Length of output: 797


🏁 Script executed:

set -euo pipefail
printf'%s\n''--- TypeDoc configuration and custom rendering references ---'
rg -n -S -i 'typedoc|signature.*render|default.*param|optional.*param|RemovePasswordParams' \
.typedoc packages package.json pnpm-workspace.yaml 2>/dev/null | head -n 240
printf'%s\n''--- Relevant snapshot and source context ---'
sed -n '1,24p' .typedoc/__tests__/__snapshots__/user-api-methods-remove-password.mdx
sed -n '700,742p' packages/backend/src/api/endpoints/UserApi.ts
printf'%s\n''--- Tests and scripts that generate or validate TypeDoc snapshots ---'
rg -n -S 'typedoc|user-api-methods-remove-password|__snapshots__' \
.github package.json .typedoc packages 2>/dev/null | head -n 240

Repository: clerk/javascript

Length of output: 50374


🏁 Script executed:

set -euo pipefail
printf'%s\n''--- Signature rendering implementation ---'
sed -n '1220,1435p' .typedoc/custom-theme.mjs
printf'%s\n''--- Optional-parameter helper implementation ---'
sed -n '420,455p' .typedoc/custom-theme.mjs
sed -n '560,605p' .typedoc/custom-theme.mjs
printf'%s\n''--- TypeDoc configuration ---'
sed -n '1,220p' typedoc.config.mjs

Repository: clerk/javascript

Length of output: 15853


🏁 Script executed:

set -euo pipefail
printf'%s\n''--- Signature-parameter hooks and custom partials ---'
rg -n -C 12 'signatureParameters|signatureParameter|isOptional|defaultValue' .typedoc/custom-theme.mjs | head -n 260
printf'%s\n''--- TypeDoc model fixtures or generated metadata for removePassword ---'
rg -n -S -C 8 'removePassword|RemovePasswordParams' .typedoc packages/backend/src/api/__tests__ packages/backend/src/api/endpoints | head -n 220
printf'%s\n''--- Comparable default-parameter signatures in snapshots ---'
rg -n -S 'function .*\([^)]*=|function .*\([^)]*\?:' .typedoc/__tests__/__snapshots__ | head -n 160

Repository: clerk/javascript

Length of output: 23999


🏁 Script executed:

set -euo pipefail
python3 - <<'PY'from pathlib import Pathimport resource = Path("packages/backend/src/api/endpoints/UserApi.ts").read_text()snapshot = Path(".typedoc/__tests__/__snapshots__/user-api-methods-remove-password.mdx").read_text()comparables = { p.name: p.read_text() for p in Path(".typedoc/__tests__/__snapshots__").glob("*.mdx")}method = re.search( r"public async removePassword\(\s*userId:\s*string,\s*params:\s*RemovePasswordParams\s*=\s*\{\}\s*\)", source,)rendered = re.search( r"function removePassword\(userId: string, params(\?)?: \{ signOutOfOtherSessions\?: boolean \}\)", snapshot,)assert method, "removePassword source declaration was not found"assert rendered, "removePassword snapshot signature was not found"print("source_default_parameter:", True)print("snapshot_params_optional:", rendered.group(1) == "?")print("snapshot_signature:", rendered.group(0))for name, text in comparables.items(): if re.search(r"function (?:signOut|sendCode)\([^)]*\?:", text): print("comparable_optional_signature:", name)PY

Repository: clerk/javascript

Length of output: 469


Render params as optional.

removePassword provides a default value for params, but the generated signature marks it as required. Update the TypeDoc signature rendering and regenerate the snapshot.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.typedoc/__tests__/__snapshots__/user-api-methods-remove-password.mdx at
line 8, Update the TypeDoc signature rendering for removePassword so its
defaulted params argument is rendered as optional, then regenerate the
user-api-methods-remove-password snapshot to reflect the corrected signature.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Skipping this one. It's semantically right — params has a = {} default, so TS declaration output would render it as params? — but the missing ? comes from formatTypeScriptSignature(), which this PR doesn't touch. The snapshot has to mirror generated output, so patching just the snapshot would make the test lie. A real fix means teaching the formatter to detect default-initialized params and regenerating every affected snapshot, which is out of scope here.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@manovotny, agreed. The snapshot must reflect the current formatter output. A snapshot-only change would be incorrect.

This finding is out of scope for this PR. A separate fix should update formatTypeScriptSignature() and regenerate all affected snapshots.

Would you like me to open a follow-up issue for that work?


✏️ Learnings added
Learnt from: manovotny
Repo: clerk/javascript PR: 9372
File: .typedoc/__tests__/__snapshots__/user-api-methods-remove-password.mdx:8-8
Timestamp: 2026-08-10T18:13:38.851Z
Learning: In the `.typedoc` documentation generator, `.typedoc/formatTypeScriptSignature()` controls parameter optionality in generated TypeScript signatures. Snapshots must mirror formatter output. Correctly rendering default-initialized parameters such as `params: RemovePasswordParams = {}` as optional requires a formatter change and regeneration of all affected snapshots.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

You are interacting with an AI system.

```

## Parameters


| Parameter | Type | Description |
| ------ | ------ | ------ |
| `userId` | `string` | The ID of the user whose password to remove. |
| `params` | <code>\{ signOutOfOtherSessions?: boolean; \}</code> | Options for the request. |
| `params.signOutOfOtherSessions?` | `boolean` | When set to `true`, all of the user's active sessions are revoked after their password is removed. Defaults to `false`. |
6 changes: 6 additions & 0 deletions .typedoc/__tests__/extract-methods.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -18,6 +18,7 @@ import { describe, expect, it } from 'vitest';
* - `methods/check-authorization.mdx` – generic instantiation (`CheckAuthorization`)
* - `methods/email-code-send-code.mdx` – qualified name from `@extractMethods` parent
* - `methods/email-link.mdx` – `@extractMethods` namespace index (non-callables)
* - `methods/remove-password.mdx` – backend page format with omitted `@example` blocks
* - `properties.mdx` (clerk) – properties table sliced from already-prettified page
* - `clerk.mdx` – main page after Properties has been stripped
* - `properties.mdx` (user-resource) – properties with external type links and metadata
Expand DownExpand Up@@ -71,6 +72,11 @@ describe('extract-methods snapshots', () => {
await expect(content).toMatchFileSnapshot('./__snapshots__/sign-in-future-resource-methods-email-link.mdx');
});

it('backend page format omits examples: users.removePassword()', async () => {
const content = await readGenerated('backend/user-api/methods/remove-password.mdx');
await expect(content).toMatchFileSnapshot('./__snapshots__/user-api-methods-remove-password.mdx');
});

it('properties extracted + prettier-aligned: clerk', async () => {
const content = await readGenerated('shared/clerk/properties.mdx');
await expect(content).toMatchFileSnapshot('./__snapshots__/clerk-properties.mdx');
Expand Down
10 changes: 7 additions & 3 deletions .typedoc/extract-methods.mjs
Original file line numberDiff line numberDiff line change
Expand Up@@ -729,15 +729,19 @@ const BLOCK_TAGS_OMITTED_FROM_EXTRACTED_METHOD_PROSE = new Set(['@param', '@type

/**
* @param {import('typedoc').Comment | undefined} comment
* @param {{ omitExamples?: boolean }} [options]
*/
function commentSummaryAndBody(comment) {
function commentSummaryAndBody(comment, options = {}) {
if (!comment) {
return '';
}
const c = applyTodoStrippingToComment(comment) ?? comment;
const summary = displayPartsToString(c.summary).trim();
const block = c.blockTags
?.filter(t => !BLOCK_TAGS_OMITTED_FROM_EXTRACTED_METHOD_PROSE.has(t.tag))
?.filter(
t =>
!BLOCK_TAGS_OMITTED_FROM_EXTRACTED_METHOD_PROSE.has(t.tag) && !(options.omitExamples && t.tag === '@example'),
)
.map(t => displayPartsToString(t.content).trim())
.filter(Boolean)
.join('\n\n');
Expand DownExpand Up@@ -1233,7 +1237,7 @@ function buildMethodMdx(decl, ctx, options = {}) {
const paramsHeadingLevel = methodFormat === 'page' ? 2 : 4;
/** Prefer the declaration comment (property-style methods document `addListener` on the property, not the signature). */
const comment = decl.comment ?? sig.comment;
let description = commentSummaryAndBody(comment);
let description = commentSummaryAndBody(comment, { omitExamples: methodFormat === 'page' });
const sigReturns = comment === sig.comment ? '' : appendSignatureOnlyReturns(decl.comment, sig.comment);
if (sigReturns) {
description = [description, sigReturns].filter(Boolean).join('\n\n');
Expand Down
2 changes: 1 addition & 1 deletion packages/backend/src/api/endpoints/UserApi.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -785,7 +785,7 @@ export class UserAPI extends AbstractAPI {
}

/**
* Locks the given [`User`](https://clerk.com/docs/reference/backend/types/backend-user), which means that they are not allowed to sign in again until the lock expires or is manually unlocked. By default, lockout duration is 1 hour, but it can be configured in the application's [**Attack protection**](https://dashboard.clerk.com/~/protect/attack-protection) settings. See the [guide on user locks](https://clerk.com/docs/guides/secure/user-lockout).
* Locks the given [`User`](https://clerk.com/docs/reference/backend/types/backend-user), which means that they are not allowed to sign in again until the lock expires or is manually unlocked. By default, lockout duration is 1 hour, but it can be configured in the application's [**Rules**](https://dashboard.clerk.com/~/protect/rules) settings. See the [guide on user locks](https://clerk.com/docs/guides/secure/user-lockout).
* @param userId - The ID of the user to lock.
*/
public async lockUser(userId: string) {
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' docs(backend): fix Dashboard links and method reference layout by SarahSoutoul · Pull Request #9372 · clerk/javascript · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/fix-lock-user-doc-link.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
---
'@clerk/backend': patch
---

Update the `lockUser()` documentation to link to the current Rules page in the Clerk Dashboard.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
Removes the password credential from the given user. This is a privileged operation and does not require the user's current password. Password removal is allowed even when the user has no other sign-in method configured.

By default, existing sessions remain active. Set `signOutOfOtherSessions` to `true` to revoke sessions active when the request is processed.

Returns the updated [`User`](/docs/reference/backend/types/backend-user).

```typescript
function removePassword(userId: string, params: { signOutOfOtherSessions?: boolean }): Promise<User>

@coderabbitaicoderabbitaiBotAug 10, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bashset -euo pipefail
source_file='packages/backend/src/api/endpoints/UserApi.ts'
snapshot_file='.typedoc/__tests__/__snapshots__/user-api-methods-remove-password.mdx'
rg -n -A3 -B2 'removePassword'"$source_file"
rg -n 'function removePassword'"$snapshot_file"if rg -q 'function removePassword\(userId: string, params: '"$snapshot_file"&&! rg -q 'function removePassword\(userId: string, params\?: '"$snapshot_file";thenecho'Generated signature marks params as required.'exit 1
fi

Repository: clerk/javascript

Length of output: 797


🏁 Script executed:

set -euo pipefail
printf'%s\n''--- TypeDoc configuration and custom rendering references ---'
rg -n -S -i 'typedoc|signature.*render|default.*param|optional.*param|RemovePasswordParams' \
.typedoc packages package.json pnpm-workspace.yaml 2>/dev/null | head -n 240
printf'%s\n''--- Relevant snapshot and source context ---'
sed -n '1,24p' .typedoc/__tests__/__snapshots__/user-api-methods-remove-password.mdx
sed -n '700,742p' packages/backend/src/api/endpoints/UserApi.ts
printf'%s\n''--- Tests and scripts that generate or validate TypeDoc snapshots ---'
rg -n -S 'typedoc|user-api-methods-remove-password|__snapshots__' \
.github package.json .typedoc packages 2>/dev/null | head -n 240

Repository: clerk/javascript

Length of output: 50374


🏁 Script executed:

set -euo pipefail
printf'%s\n''--- Signature rendering implementation ---'
sed -n '1220,1435p' .typedoc/custom-theme.mjs
printf'%s\n''--- Optional-parameter helper implementation ---'
sed -n '420,455p' .typedoc/custom-theme.mjs
sed -n '560,605p' .typedoc/custom-theme.mjs
printf'%s\n''--- TypeDoc configuration ---'
sed -n '1,220p' typedoc.config.mjs

Repository: clerk/javascript

Length of output: 15853


🏁 Script executed:

set -euo pipefail
printf'%s\n''--- Signature-parameter hooks and custom partials ---'
rg -n -C 12 'signatureParameters|signatureParameter|isOptional|defaultValue' .typedoc/custom-theme.mjs | head -n 260
printf'%s\n''--- TypeDoc model fixtures or generated metadata for removePassword ---'
rg -n -S -C 8 'removePassword|RemovePasswordParams' .typedoc packages/backend/src/api/__tests__ packages/backend/src/api/endpoints | head -n 220
printf'%s\n''--- Comparable default-parameter signatures in snapshots ---'
rg -n -S 'function .*\([^)]*=|function .*\([^)]*\?:' .typedoc/__tests__/__snapshots__ | head -n 160

Repository: clerk/javascript

Length of output: 23999


🏁 Script executed:

set -euo pipefail
python3 - <<'PY'from pathlib import Pathimport resource = Path("packages/backend/src/api/endpoints/UserApi.ts").read_text()snapshot = Path(".typedoc/__tests__/__snapshots__/user-api-methods-remove-password.mdx").read_text()comparables = { p.name: p.read_text() for p in Path(".typedoc/__tests__/__snapshots__").glob("*.mdx")}method = re.search( r"public async removePassword\(\s*userId:\s*string,\s*params:\s*RemovePasswordParams\s*=\s*\{\}\s*\)", source,)rendered = re.search( r"function removePassword\(userId: string, params(\?)?: \{ signOutOfOtherSessions\?: boolean \}\)", snapshot,)assert method, "removePassword source declaration was not found"assert rendered, "removePassword snapshot signature was not found"print("source_default_parameter:", True)print("snapshot_params_optional:", rendered.group(1) == "?")print("snapshot_signature:", rendered.group(0))for name, text in comparables.items(): if re.search(r"function (?:signOut|sendCode)\([^)]*\?:", text): print("comparable_optional_signature:", name)PY

Repository: clerk/javascript

Length of output: 469


Render params as optional.

removePassword provides a default value for params, but the generated signature marks it as required. Update the TypeDoc signature rendering and regenerate the snapshot.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.typedoc/__tests__/__snapshots__/user-api-methods-remove-password.mdx at
line 8, Update the TypeDoc signature rendering for removePassword so its
defaulted params argument is rendered as optional, then regenerate the
user-api-methods-remove-password snapshot to reflect the corrected signature.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Skipping this one. It's semantically right — params has a = {} default, so TS declaration output would render it as params? — but the missing ? comes from formatTypeScriptSignature(), which this PR doesn't touch. The snapshot has to mirror generated output, so patching just the snapshot would make the test lie. A real fix means teaching the formatter to detect default-initialized params and regenerating every affected snapshot, which is out of scope here.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@manovotny, agreed. The snapshot must reflect the current formatter output. A snapshot-only change would be incorrect.

This finding is out of scope for this PR. A separate fix should update formatTypeScriptSignature() and regenerate all affected snapshots.

Would you like me to open a follow-up issue for that work?


✏️ Learnings added
Learnt from: manovotny
Repo: clerk/javascript PR: 9372
File: .typedoc/__tests__/__snapshots__/user-api-methods-remove-password.mdx:8-8
Timestamp: 2026-08-10T18:13:38.851Z
Learning: In the `.typedoc` documentation generator, `.typedoc/formatTypeScriptSignature()` controls parameter optionality in generated TypeScript signatures. Snapshots must mirror formatter output. Correctly rendering default-initialized parameters such as `params: RemovePasswordParams = {}` as optional requires a formatter change and regeneration of all affected snapshots.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

You are interacting with an AI system.

```

## Parameters


| Parameter | Type | Description |
| ------ | ------ | ------ |
| `userId` | `string` | The ID of the user whose password to remove. |
| `params` | <code>\{ signOutOfOtherSessions?: boolean; \}</code> | Options for the request. |
| `params.signOutOfOtherSessions?` | `boolean` | When set to `true`, all of the user's active sessions are revoked after their password is removed. Defaults to `false`. |
6 changes: 6 additions & 0 deletions .typedoc/__tests__/extract-methods.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -18,6 +18,7 @@ import { describe, expect, it } from 'vitest';
* - `methods/check-authorization.mdx` – generic instantiation (`CheckAuthorization`)
* - `methods/email-code-send-code.mdx` – qualified name from `@extractMethods` parent
* - `methods/email-link.mdx` – `@extractMethods` namespace index (non-callables)
* - `methods/remove-password.mdx` – backend page format with omitted `@example` blocks
* - `properties.mdx` (clerk) – properties table sliced from already-prettified page
* - `clerk.mdx` – main page after Properties has been stripped
* - `properties.mdx` (user-resource) – properties with external type links and metadata
Expand DownExpand Up@@ -71,6 +72,11 @@ describe('extract-methods snapshots', () => {
await expect(content).toMatchFileSnapshot('./__snapshots__/sign-in-future-resource-methods-email-link.mdx');
});

it('backend page format omits examples: users.removePassword()', async () => {
const content = await readGenerated('backend/user-api/methods/remove-password.mdx');
await expect(content).toMatchFileSnapshot('./__snapshots__/user-api-methods-remove-password.mdx');
});

it('properties extracted + prettier-aligned: clerk', async () => {
const content = await readGenerated('shared/clerk/properties.mdx');
await expect(content).toMatchFileSnapshot('./__snapshots__/clerk-properties.mdx');
Expand Down
10 changes: 7 additions & 3 deletions .typedoc/extract-methods.mjs
Original file line numberDiff line numberDiff line change
Expand Up@@ -729,15 +729,19 @@ const BLOCK_TAGS_OMITTED_FROM_EXTRACTED_METHOD_PROSE = new Set(['@param', '@type

/**
* @param {import('typedoc').Comment | undefined} comment
* @param {{ omitExamples?: boolean }} [options]
*/
function commentSummaryAndBody(comment) {
function commentSummaryAndBody(comment, options = {}) {
if (!comment) {
return '';
}
const c = applyTodoStrippingToComment(comment) ?? comment;
const summary = displayPartsToString(c.summary).trim();
const block = c.blockTags
?.filter(t => !BLOCK_TAGS_OMITTED_FROM_EXTRACTED_METHOD_PROSE.has(t.tag))
?.filter(
t =>
!BLOCK_TAGS_OMITTED_FROM_EXTRACTED_METHOD_PROSE.has(t.tag) && !(options.omitExamples && t.tag === '@example'),
)
.map(t => displayPartsToString(t.content).trim())
.filter(Boolean)
.join('\n\n');
Expand DownExpand Up@@ -1233,7 +1237,7 @@ function buildMethodMdx(decl, ctx, options = {}) {
const paramsHeadingLevel = methodFormat === 'page' ? 2 : 4;
/** Prefer the declaration comment (property-style methods document `addListener` on the property, not the signature). */
const comment = decl.comment ?? sig.comment;
let description = commentSummaryAndBody(comment);
let description = commentSummaryAndBody(comment, { omitExamples: methodFormat === 'page' });
const sigReturns = comment === sig.comment ? '' : appendSignatureOnlyReturns(decl.comment, sig.comment);
if (sigReturns) {
description = [description, sigReturns].filter(Boolean).join('\n\n');
Expand Down
2 changes: 1 addition & 1 deletion packages/backend/src/api/endpoints/UserApi.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -785,7 +785,7 @@ export class UserAPI extends AbstractAPI {
}

/**
* Locks the given [`User`](https://clerk.com/docs/reference/backend/types/backend-user), which means that they are not allowed to sign in again until the lock expires or is manually unlocked. By default, lockout duration is 1 hour, but it can be configured in the application's [**Attack protection**](https://dashboard.clerk.com/~/protect/attack-protection) settings. See the [guide on user locks](https://clerk.com/docs/guides/secure/user-lockout).
* Locks the given [`User`](https://clerk.com/docs/reference/backend/types/backend-user), which means that they are not allowed to sign in again until the lock expires or is manually unlocked. By default, lockout duration is 1 hour, but it can be configured in the application's [**Rules**](https://dashboard.clerk.com/~/protect/rules) settings. See the [guide on user locks](https://clerk.com/docs/guides/secure/user-lockout).
* @param userId - The ID of the user to lock.
*/
public async lockUser(userId: string) {
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); docs(backend): fix Dashboard links and method reference layout by SarahSoutoul · Pull Request #9372 · clerk/javascript · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/fix-lock-user-doc-link.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
---
'@clerk/backend': patch
---

Update the `lockUser()` documentation to link to the current Rules page in the Clerk Dashboard.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
Removes the password credential from the given user. This is a privileged operation and does not require the user's current password. Password removal is allowed even when the user has no other sign-in method configured.

By default, existing sessions remain active. Set `signOutOfOtherSessions` to `true` to revoke sessions active when the request is processed.

Returns the updated [`User`](/docs/reference/backend/types/backend-user).

```typescript
function removePassword(userId: string, params: { signOutOfOtherSessions?: boolean }): Promise<User>

@coderabbitaicoderabbitaiBotAug 10, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bashset -euo pipefail
source_file='packages/backend/src/api/endpoints/UserApi.ts'
snapshot_file='.typedoc/__tests__/__snapshots__/user-api-methods-remove-password.mdx'
rg -n -A3 -B2 'removePassword'"$source_file"
rg -n 'function removePassword'"$snapshot_file"if rg -q 'function removePassword\(userId: string, params: '"$snapshot_file"&&! rg -q 'function removePassword\(userId: string, params\?: '"$snapshot_file";thenecho'Generated signature marks params as required.'exit 1
fi

Repository: clerk/javascript

Length of output: 797


🏁 Script executed:

set -euo pipefail
printf'%s\n''--- TypeDoc configuration and custom rendering references ---'
rg -n -S -i 'typedoc|signature.*render|default.*param|optional.*param|RemovePasswordParams' \
.typedoc packages package.json pnpm-workspace.yaml 2>/dev/null | head -n 240
printf'%s\n''--- Relevant snapshot and source context ---'
sed -n '1,24p' .typedoc/__tests__/__snapshots__/user-api-methods-remove-password.mdx
sed -n '700,742p' packages/backend/src/api/endpoints/UserApi.ts
printf'%s\n''--- Tests and scripts that generate or validate TypeDoc snapshots ---'
rg -n -S 'typedoc|user-api-methods-remove-password|__snapshots__' \
.github package.json .typedoc packages 2>/dev/null | head -n 240

Repository: clerk/javascript

Length of output: 50374


🏁 Script executed:

set -euo pipefail
printf'%s\n''--- Signature rendering implementation ---'
sed -n '1220,1435p' .typedoc/custom-theme.mjs
printf'%s\n''--- Optional-parameter helper implementation ---'
sed -n '420,455p' .typedoc/custom-theme.mjs
sed -n '560,605p' .typedoc/custom-theme.mjs
printf'%s\n''--- TypeDoc configuration ---'
sed -n '1,220p' typedoc.config.mjs

Repository: clerk/javascript

Length of output: 15853


🏁 Script executed:

set -euo pipefail
printf'%s\n''--- Signature-parameter hooks and custom partials ---'
rg -n -C 12 'signatureParameters|signatureParameter|isOptional|defaultValue' .typedoc/custom-theme.mjs | head -n 260
printf'%s\n''--- TypeDoc model fixtures or generated metadata for removePassword ---'
rg -n -S -C 8 'removePassword|RemovePasswordParams' .typedoc packages/backend/src/api/__tests__ packages/backend/src/api/endpoints | head -n 220
printf'%s\n''--- Comparable default-parameter signatures in snapshots ---'
rg -n -S 'function .*\([^)]*=|function .*\([^)]*\?:' .typedoc/__tests__/__snapshots__ | head -n 160

Repository: clerk/javascript

Length of output: 23999


🏁 Script executed:

set -euo pipefail
python3 - <<'PY'from pathlib import Pathimport resource = Path("packages/backend/src/api/endpoints/UserApi.ts").read_text()snapshot = Path(".typedoc/__tests__/__snapshots__/user-api-methods-remove-password.mdx").read_text()comparables = { p.name: p.read_text() for p in Path(".typedoc/__tests__/__snapshots__").glob("*.mdx")}method = re.search( r"public async removePassword\(\s*userId:\s*string,\s*params:\s*RemovePasswordParams\s*=\s*\{\}\s*\)", source,)rendered = re.search( r"function removePassword\(userId: string, params(\?)?: \{ signOutOfOtherSessions\?: boolean \}\)", snapshot,)assert method, "removePassword source declaration was not found"assert rendered, "removePassword snapshot signature was not found"print("source_default_parameter:", True)print("snapshot_params_optional:", rendered.group(1) == "?")print("snapshot_signature:", rendered.group(0))for name, text in comparables.items(): if re.search(r"function (?:signOut|sendCode)\([^)]*\?:", text): print("comparable_optional_signature:", name)PY

Repository: clerk/javascript

Length of output: 469


Render params as optional.

removePassword provides a default value for params, but the generated signature marks it as required. Update the TypeDoc signature rendering and regenerate the snapshot.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.typedoc/__tests__/__snapshots__/user-api-methods-remove-password.mdx at
line 8, Update the TypeDoc signature rendering for removePassword so its
defaulted params argument is rendered as optional, then regenerate the
user-api-methods-remove-password snapshot to reflect the corrected signature.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Skipping this one. It's semantically right — params has a = {} default, so TS declaration output would render it as params? — but the missing ? comes from formatTypeScriptSignature(), which this PR doesn't touch. The snapshot has to mirror generated output, so patching just the snapshot would make the test lie. A real fix means teaching the formatter to detect default-initialized params and regenerating every affected snapshot, which is out of scope here.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@manovotny, agreed. The snapshot must reflect the current formatter output. A snapshot-only change would be incorrect.

This finding is out of scope for this PR. A separate fix should update formatTypeScriptSignature() and regenerate all affected snapshots.

Would you like me to open a follow-up issue for that work?


✏️ Learnings added
Learnt from: manovotny
Repo: clerk/javascript PR: 9372
File: .typedoc/__tests__/__snapshots__/user-api-methods-remove-password.mdx:8-8
Timestamp: 2026-08-10T18:13:38.851Z
Learning: In the `.typedoc` documentation generator, `.typedoc/formatTypeScriptSignature()` controls parameter optionality in generated TypeScript signatures. Snapshots must mirror formatter output. Correctly rendering default-initialized parameters such as `params: RemovePasswordParams = {}` as optional requires a formatter change and regeneration of all affected snapshots.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

You are interacting with an AI system.

```

## Parameters


| Parameter | Type | Description |
| ------ | ------ | ------ |
| `userId` | `string` | The ID of the user whose password to remove. |
| `params` | <code>\{ signOutOfOtherSessions?: boolean; \}</code> | Options for the request. |
| `params.signOutOfOtherSessions?` | `boolean` | When set to `true`, all of the user's active sessions are revoked after their password is removed. Defaults to `false`. |
6 changes: 6 additions & 0 deletions .typedoc/__tests__/extract-methods.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -18,6 +18,7 @@ import { describe, expect, it } from 'vitest';
* - `methods/check-authorization.mdx` – generic instantiation (`CheckAuthorization`)
* - `methods/email-code-send-code.mdx` – qualified name from `@extractMethods` parent
* - `methods/email-link.mdx` – `@extractMethods` namespace index (non-callables)
* - `methods/remove-password.mdx` – backend page format with omitted `@example` blocks
* - `properties.mdx` (clerk) – properties table sliced from already-prettified page
* - `clerk.mdx` – main page after Properties has been stripped
* - `properties.mdx` (user-resource) – properties with external type links and metadata
Expand DownExpand Up@@ -71,6 +72,11 @@ describe('extract-methods snapshots', () => {
await expect(content).toMatchFileSnapshot('./__snapshots__/sign-in-future-resource-methods-email-link.mdx');
});

it('backend page format omits examples: users.removePassword()', async () => {
const content = await readGenerated('backend/user-api/methods/remove-password.mdx');
await expect(content).toMatchFileSnapshot('./__snapshots__/user-api-methods-remove-password.mdx');
});

it('properties extracted + prettier-aligned: clerk', async () => {
const content = await readGenerated('shared/clerk/properties.mdx');
await expect(content).toMatchFileSnapshot('./__snapshots__/clerk-properties.mdx');
Expand Down
10 changes: 7 additions & 3 deletions .typedoc/extract-methods.mjs
Original file line numberDiff line numberDiff line change
Expand Up@@ -729,15 +729,19 @@ const BLOCK_TAGS_OMITTED_FROM_EXTRACTED_METHOD_PROSE = new Set(['@param', '@type

/**
* @param {import('typedoc').Comment | undefined} comment
* @param {{ omitExamples?: boolean }} [options]
*/
function commentSummaryAndBody(comment) {
function commentSummaryAndBody(comment, options = {}) {
if (!comment) {
return '';
}
const c = applyTodoStrippingToComment(comment) ?? comment;
const summary = displayPartsToString(c.summary).trim();
const block = c.blockTags
?.filter(t => !BLOCK_TAGS_OMITTED_FROM_EXTRACTED_METHOD_PROSE.has(t.tag))
?.filter(
t =>
!BLOCK_TAGS_OMITTED_FROM_EXTRACTED_METHOD_PROSE.has(t.tag) && !(options.omitExamples && t.tag === '@example'),
)
.map(t => displayPartsToString(t.content).trim())
.filter(Boolean)
.join('\n\n');
Expand DownExpand Up@@ -1233,7 +1237,7 @@ function buildMethodMdx(decl, ctx, options = {}) {
const paramsHeadingLevel = methodFormat === 'page' ? 2 : 4;
/** Prefer the declaration comment (property-style methods document `addListener` on the property, not the signature). */
const comment = decl.comment ?? sig.comment;
let description = commentSummaryAndBody(comment);
let description = commentSummaryAndBody(comment, { omitExamples: methodFormat === 'page' });
const sigReturns = comment === sig.comment ? '' : appendSignatureOnlyReturns(decl.comment, sig.comment);
if (sigReturns) {
description = [description, sigReturns].filter(Boolean).join('\n\n');
Expand Down
2 changes: 1 addition & 1 deletion packages/backend/src/api/endpoints/UserApi.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -785,7 +785,7 @@ export class UserAPI extends AbstractAPI {
}

/**
* Locks the given [`User`](https://clerk.com/docs/reference/backend/types/backend-user), which means that they are not allowed to sign in again until the lock expires or is manually unlocked. By default, lockout duration is 1 hour, but it can be configured in the application's [**Attack protection**](https://dashboard.clerk.com/~/protect/attack-protection) settings. See the [guide on user locks](https://clerk.com/docs/guides/secure/user-lockout).
* Locks the given [`User`](https://clerk.com/docs/reference/backend/types/backend-user), which means that they are not allowed to sign in again until the lock expires or is manually unlocked. By default, lockout duration is 1 hour, but it can be configured in the application's [**Rules**](https://dashboard.clerk.com/~/protect/rules) settings. See the [guide on user locks](https://clerk.com/docs/guides/secure/user-lockout).
* @param userId - The ID of the user to lock.
*/
public async lockUser(userId: string) {
Expand Down
Loading