Skip to content

Commit 86b3e8f

Browse files
committed
fix TODO handling; add some links to custom-plugin
1 parent 4347350 commit 86b3e8f

6 files changed

Lines changed: 122 additions & 28 deletions

File tree

.typedoc/comment-utils.mjs

Lines changed: 72 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// @ts-check
22
import { Comment } from 'typedoc';
33

4-
const TODO_IN_COMMENT = /\bTODO\b/i;
4+
const TODO_WORD = /\bTODO\b/i;
55

66
/**
77
* @param {import('typedoc').Comment | undefined} comment
@@ -19,5 +19,75 @@ export function commentContainsTodo(comment) {
1919
chunks.push(Comment.combineDisplayParts(tag.content));
2020
}
2121
}
22-
return chunks.some(text => TODO_IN_COMMENT.test(text));
22+
return chunks.some(text => TODO_WORD.test(text));
23+
}
24+
25+
/**
26+
* Truncate at the first word "TODO" (case-insensitive). Used when flattening display parts to a string.
27+
*
28+
* @param {string} text
29+
*/
30+
export function stripTextAfterTodo(text) {
31+
if (!text) {
32+
return '';
33+
}
34+
const m = TODO_WORD.exec(text);
35+
if (!m) {
36+
return text;
37+
}
38+
return text.slice(0, m.index).trimEnd();
39+
}
40+
41+
/**
42+
* Drop display parts from the first `TODO` onward; truncate the containing text part if `TODO` appears mid-string.
43+
*
44+
* @param {import('typedoc').CommentDisplayPart[] | undefined} parts
45+
* @returns {import('typedoc').CommentDisplayPart[]}
46+
*/
47+
function stripTodoFromDisplayParts(parts) {
48+
if (!parts?.length) {
49+
return parts ?? [];
50+
}
51+
/** @type {import('typedoc').CommentDisplayPart[]} */
52+
const out = [];
53+
for (const p of parts) {
54+
if (p.kind === 'text' && 'text' in p && typeof p.text === 'string') {
55+
const match = TODO_WORD.exec(p.text);
56+
if (match) {
57+
const before = p.text.slice(0, match.index).trimEnd();
58+
if (before.length) {
59+
out.push(/** @type {import('typedoc').CommentDisplayPart} */ ({ kind: 'text', text: before }));
60+
}
61+
return out;
62+
}
63+
}
64+
out.push(p);
65+
}
66+
return out;
67+
}
68+
69+
/**
70+
* Returns a clone with `TODO` and everything after it removed from the summary and from any block tag that contains `TODO`.
71+
* Comments without `TODO` are returned unchanged (same reference). Undefined in, undefined out.
72+
*
73+
* @param {import('typedoc').Comment | undefined} comment
74+
* @returns {import('typedoc').Comment | undefined}
75+
*/
76+
export function applyTodoStrippingToComment(comment) {
77+
if (!comment) {
78+
return undefined;
79+
}
80+
if (!commentContainsTodo(comment)) {
81+
return comment;
82+
}
83+
const c = comment.clone();
84+
if (c.summary?.length && TODO_WORD.test(Comment.combineDisplayParts(c.summary))) {
85+
c.summary = stripTodoFromDisplayParts(c.summary);
86+
}
87+
for (const tag of c.blockTags ?? []) {
88+
if (tag.content?.length && TODO_WORD.test(Comment.combineDisplayParts(tag.content))) {
89+
tag.content = stripTodoFromDisplayParts(tag.content);
90+
}
91+
}
92+
return c;
2393
}

.typedoc/custom-plugin.mjs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,10 +222,18 @@ function getCatchAllReplacements() {
222222
replace: (/** @type {string} */ _match, /** @type {string} */ type) =>
223223
`[\`${type}\`](/docs/reference/types/errors)`,
224224
},
225+
{
226+
pattern: /(?<![\[\w`#])`?SignInFirstFactor`?(?![\]\w`])/g,
227+
replace: '[SignInFirstFactor](/docs/reference/types/sign-in-first-factor)',
228+
},
225229
{
226230
pattern: /(?<![\[\w`#])`?SignInFutureResource`?(?![\]\w`])/g,
227231
replace: '[SignInFutureResource](/docs/reference/objects/sign-in-future)',
228232
},
233+
{
234+
pattern: /(?<![\[\w`#])`?SignInSecondFactor`?(?![\]\w`])/g,
235+
replace: '[SignInSecondFactor](/docs/reference/types/sign-in-second-factor)',
236+
},
229237
{
230238
pattern: /(?<![\[\w`#])`?SignedInSessionResource`?(?![\]\w`])/g,
231239
replace: '[SignedInSessionResource](/docs/reference/objects/session)',
@@ -314,6 +322,10 @@ function getCatchAllReplacements() {
314322
pattern: /(?<![\[\w`#])`?Web3WalletResource`?(?![\]\w`])/g,
315323
replace: '[Web3WalletResource](/docs/reference/types/web3-wallet)',
316324
},
325+
{
326+
pattern: /(?<![\[\w`#])`?VerificationResource`?(?![\]\w`])/g,
327+
replace: '[VerificationResource](/docs/reference/types/verification-resource)',
328+
},
317329
{
318330
/**
319331
* By default, `@deprecated` is output with `**Deprecated**`. We want to add a full stop to it.

.typedoc/custom-theme.mjs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {
1010
import { removeLineBreaks } from '../node_modules/typedoc-plugin-markdown/dist/libs/utils/index.js';
1111
import { TypeDeclarationVisibility } from '../node_modules/typedoc-plugin-markdown/dist/options/maps.js';
1212

13-
import { commentContainsTodo } from './comment-utils.mjs';
13+
import { applyTodoStrippingToComment } from './comment-utils.mjs';
1414
import { REFERENCE_OBJECTS_LIST } from './reference-objects.mjs';
1515

1616
export { REFERENCE_OBJECTS_LIST };
@@ -876,18 +876,19 @@ class ClerkMarkdownThemeContext extends MarkdownThemeContext {
876876
* @param {Parameters<typeof superPartials.comment>[1]} [options]
877877
*/
878878
comment: (model, options) => {
879-
if (commentContainsTodo(model)) {
880-
return '';
879+
if (!model) {
880+
return superPartials.comment.call(this, model, options);
881881
}
882+
const modelToRender = applyTodoStrippingToComment(model) ?? model;
882883
const hidden = new Set(['@inline', '@inlineType', '@experimental']);
883-
const modTags = model?.modifierTags ? Array.from(model.modifierTags) : [];
884+
const modTags = Array.from(modelToRender.modifierTags ?? []);
884885
if (modTags.some(/** @param {string} t */ t => hidden.has(t))) {
885-
const clone = Object.assign(Object.create(Object.getPrototypeOf(model)), model, {
886+
const clone = Object.assign(Object.create(Object.getPrototypeOf(modelToRender)), modelToRender, {
886887
modifierTags: new Set(modTags.filter(/** @param {string} t */ t => !hidden.has(t))),
887888
});
888889
return superPartials.comment.call(this, clone, options);
889890
}
890-
return superPartials.comment.call(this, model, options);
891+
return superPartials.comment.call(this, modelToRender, options);
891892
},
892893
/**
893894
* Remove the blockquote signature line.

.typedoc/extract-methods.mjs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ import {
3333
stripReferenceObjectPropertiesSection,
3434
} from './custom-plugin.mjs';
3535
import { prepareMarkdownRenderer } from './prepare-markdown-renderer.mjs';
36-
import { commentContainsTodo } from './comment-utils.mjs';
36+
import { applyTodoStrippingToComment } from './comment-utils.mjs';
3737
import { REFERENCE_OBJECTS_LIST, REFERENCE_OBJECT_CONFIG } from './reference-objects.mjs';
3838

3939
const __filename = fileURLToPath(import.meta.url);
@@ -560,10 +560,12 @@ function buildPropertyTableDocMdx(parentName, nestedDecl, ctx) {
560560
const qualifiedName = `${parentName}.${nestedDecl.name}`;
561561
const title = `### \`${qualifiedName}\``;
562562
const description = commentSummaryAndBody(nestedDecl.comment);
563-
const props = resolveObjectShapeMembersForPropertyTable(nestedDecl.type);
564-
if (!props?.length) {
563+
const propsUnsorted = resolveObjectShapeMembersForPropertyTable(nestedDecl.type);
564+
if (!propsUnsorted?.length) {
565565
return '';
566566
}
567+
/** Match nominal param tables and merged intersection holders: stable A–Z by property name (TypeDoc inline literal `children` order is declaration order). */
568+
const props = [...propsUnsorted].sort((a, b) => a.name.localeCompare(b.name));
567569
const tableMd = renderMemberTableOmittingExampleBlocks(props, ctx, () =>
568570
ctx.partials.propertiesTable(
569571
props,
@@ -762,17 +764,18 @@ const BLOCK_TAGS_OMITTED_FROM_EXTRACTED_METHOD_PROSE = new Set(['@param', '@type
762764
* @param {import('typedoc').Comment | undefined} comment
763765
*/
764766
function commentSummaryAndBody(comment) {
765-
if (!comment || commentContainsTodo(comment)) {
767+
if (!comment) {
766768
return '';
767769
}
768-
const summary = displayPartsToString(comment.summary).trim();
769-
const block = comment.blockTags
770+
const c = applyTodoStrippingToComment(comment) ?? comment;
771+
const summary = displayPartsToString(c.summary).trim();
772+
const block = c.blockTags
770773
?.filter(t => !BLOCK_TAGS_OMITTED_FROM_EXTRACTED_METHOD_PROSE.has(t.tag))
771774
.map(t => displayPartsToString(t.content).trim())
772775
.filter(Boolean)
773776
.join('\n\n');
774777
const returnsLines =
775-
comment.blockTags
778+
c.blockTags
776779
?.filter(t => t.tag === '@returns')
777780
.map(t => formatReturnsLineFromTag(t))
778781
.filter(Boolean) ?? [];

packages/shared/src/types/signInCommon.ts

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -57,16 +57,6 @@ import type {
5757
} from './strategies';
5858
import type { StartEmailLinkFlowParams } from './verification';
5959

60-
/**
61-
* @property {string} 'needs_identifier' - The user's identifier (e.g., email address, phone number, username) hasn't been provided.
62-
* @property {string} 'needs_first_factor' - One of the following [first factor verification](!first-factor-verification) strategies is missing: `'email_link'`, `'email_code'`, `passkey`, `password`, `'phone_code'`, `'web3_base_signature'`, `'web3_metamask_signature'`, `'web3_coinbase_wallet_signature'`, `'web3_okx_wallet_signature'`, `'web3_solana_signature'`, [`OAuthStrategy`](https://clerk.com/docs/reference/types/sso#o-auth-strategy), or `'enterprise_sso'`.
63-
* @property {string} 'needs_second_factor' - One of the following [second factor verification](!second-factor-verification) strategies is missing: `'phone_code'`, `'totp'`, `'backup_code'`, `'email_code'`, or `'email_link'`.
64-
* @property {string} 'needs_client_trust' - The user is signing in from a new device and must complete a [second factor verification](!second-factor-verification) to establish [Client Trust](https://clerk.com/docs/guides/secure/client-trust). See the [Client Trust custom flow guide](https://clerk.com/docs/guides/development/custom-flows/authentication/client-trust) for more information.
65-
* @property {string} 'needs_new_password' - The user needs to set a new password. See the [dedicated custom flow](https://clerk.com/docs/guides/development/custom-flows/account-updates/forgot-password) guide for more information.
66-
*
67-
* @interface
68-
* @inline
69-
*/
7060
export type SignInStatus =
7161
| 'needs_identifier'
7262
| 'needs_first_factor'

packages/shared/src/types/signInFuture.ts

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -223,8 +223,8 @@ export interface SignInFutureSSOParams {
223223
*/
224224
oidcPrompt?: string;
225225
/**
226-
* @experimental
227226
* The identifier of the enterprise connection to target when using the `enterprise_sso` strategy.
227+
* @experimental
228228
*/
229229
enterpriseConnectionId?: string;
230230
/**
@@ -331,6 +331,14 @@ export interface SignInFutureResource {
331331

332332
/**
333333
* The current status of the sign-in.
334+
* <ul>
335+
* <li>`'complete'` - The sign-in process has been completed successfully.</li>
336+
* <li>`'needs_client_trust'` - The user is signing in from a new device and must complete a [second factor verification](!second-factor-verification) to establish [Client Trust](https://clerk.com/docs/guides/secure/client-trust). See the [Client Trust custom flow guide](https://clerk.com/docs/guides/development/custom-flows/authentication/client-trust) for more information.</li>
337+
* <li>`'needs_identifier'` - The user's identifier (e.g., email address, phone number, username) hasn't been provided.</li>
338+
* <li>`'needs_first_factor'` - One of the following [first factor verification](!first-factor-verification) strategies is missing: `'email_link'`, `'email_code'`, `passkey`, `password`, `'phone_code'`, `'web3_base_signature'`, `'web3_metamask_signature'`, `'web3_coinbase_wallet_signature'`, `'web3_okx_wallet_signature'`, `'web3_solana_signature'`, [`OAuthStrategy`](https://clerk.com/docs/reference/types/sso#o-auth-strategy), or `'enterprise_sso'`.</li>
339+
* <li>`'needs_second_factor'` - One of the following [second factor verification](!second-factor-verification) strategies is missing: `'phone_code'`, `'totp'`, `'backup_code'`, `'email_code'`, or `'email_link'`.</li>
340+
* <li>`'needs_new_password'` - The user needs to set a new password. See the [dedicated custom flow](https://clerk.com/docs/guides/development/custom-flows/account-updates/forgot-password) guide for more information.</li>
341+
* </ul>
334342
*/
335343
readonly status: SignInStatus;
336344

@@ -341,9 +349,13 @@ export interface SignInFutureResource {
341349

342350
/**
343351
* Reflects that the sign-in was not able to create a new session because the identifier already exists in an existing session.
344-
* @property {string} sessionId - The ID of the existing session.
345352
*/
346-
readonly existingSession?: { sessionId: string };
353+
readonly existingSession?: {
354+
/**
355+
* The ID of the existing session.
356+
*/
357+
sessionId: string;
358+
};
347359

348360
/**
349361
* The state of the verification process for the selected first factor. Initially, this property contains an empty verification object, since there is no first factor selected.
@@ -367,6 +379,12 @@ export interface SignInFutureResource {
367379

368380
/**
369381
* An object containing information about the user of the current sign-in. This property is populated only once an identifier is given to the `SignIn` object through `signIn.create()` or another method that populates the `identifier` property.
382+
* <ul>
383+
* <li>`'firstName'`: The user's first name.</li>
384+
* <li>`'lastName'`: The user's last name.</li>
385+
* <li>`'imageUrl'`: The user's profile image URL.</li>
386+
* <li>`'hasImage'`: Whether the user has a profile image.</li>
387+
* </ul>
370388
*/
371389
readonly userData: UserData;
372390

0 commit comments

Comments
 (0)