Skip to content

refactor(repo): Inline extract-methods + tighten parameter rendering#8637

Open
alexisintech wants to merge 11 commits into
aa/generate-object-docsfrom
aa/generate-objects-docs-part2
Open

refactor(repo): Inline extract-methods + tighten parameter rendering#8637
alexisintech wants to merge 11 commits into
aa/generate-object-docsfrom
aa/generate-objects-docs-part2

Conversation

@alexisintech
Copy link
Copy Markdown
Member

@alexisintech alexisintech commented May 22, 2026

Stacked on top of #8276 — review that one first.

Five independent refactors of .typedoc/ (each its own commit) plus snapshot tests to lock the contract for future changes.

Summary

  • Run extract-methods inside the markdown render pass — folds extract-methods.mjs into a MarkdownPageEvent.END listener that queues a preWriteAsyncJob. Removes the second Application.bootstrapWithPlugins + convert() and the prepare-markdown-renderer.mjs workaround it required.
  • Consolidate unwrap + slug helpers — three unwrap-optional helpers + a peel-all while-loop collapse into a single unwrapOptional(t, { deep }). The two toKebabCase flavors (one for method filenames, one for page URLs) move into .typedoc/slug.mjs — they intentionally differ on acronyms, so the module exports both rather than unifying.
  • Flatten params with optionality-aware separatorclerkParametersTable.flattenParams now joins parent.child with ?. when the parent is optional and . when required. Lets us delete formatMethodParametersTable (the regex post-process that did a blanket .?. rename plus a no-longer-needed reorder).
  • Inline markdown helpers, drop node_modules importscustom-theme.mjs and extract-methods.mjs were reaching into node_modules/typedoc-plugin-markdown/dist/libs/... for backTicks, heading, htmlTable, table, removeLineBreaks, and the TypeDeclarationVisibility enum — none of which the plugin exports publicly, so that coupling broke on any dependency update. The five utilities (plus their escapeChars / formatTableCell dependencies) are now inlined in .typedoc/markdown-helpers.mjs, and the enum check is replaced with the underlying string literal ('compact').
  • Consolidate property merge across intersection/union/generic arms — three branches of resolveDeclarationWithObjectMembers duplicated the same "filter to Property, dedupe by name, sort" pattern, each wrapping the result in a synthetic holder (__intersectionMerged / __unionMerged / __referenceMerged) just so callers could read .children. Extracts mergePropertyArms(arms, options); union arms pass { skipNever: true, pickBetter: true } to drop prop?: never discriminators. The resolver now returns DeclarationReflection[] directly, and all four callers consume the array.

Also adds the snapshot dir to .prettierignore: lint-staged was silently transforming the committed snapshots after vitest run passed, leaving them out of sync with the raw output that extract-methods.mjs writes.

Output changes

Output is byte-identical to the pre-refactor baseline (diff -r, 695/695 files) for the first, second, fourth, and fifth commits. The third commit deliberately changes 8 files to fix a latent inconsistency:

  • shared/clerk/methods/handle-email-link-verification.mdx: parent params is required, children now render as params.foo (was params?.foo).
  • backend/get-auth-fn.mdx, backend/get-auth-fn-no-request.mdx, nextjs/current-user.mdx, shared/api-keys-namespace.mdx, shared/custom-navigation.mdx, shared/get-memberships.mdx, shared/on-event-listener.mdx: parent is optional, children now render as parent?.foo (was parent.foo).

All eight match the rule "separator reflects how the property would be accessed at runtime."

Test plan

  • pnpm typedoc:generate succeeds with no errors.
  • cd .typedoc && vitest run passes (11 new file-snapshot tests + the existing file-structure tests, 16 total).
  • Spot-check the 8 changed files in the rendered docs preview to confirm they read correctly.

🤖 Generated with Claude Code

alexisintech and others added 3 commits May 22, 2026 16:03
Folds extract-methods.mjs into a MarkdownPageEvent.END listener that queues a
preWriteAsyncJob, removing the second TypeDoc convert pass and its
prepare-markdown-renderer.mjs workaround. Output is byte-identical to the
prior two-pass flow (verified by full `diff -r`, 695/695 files); adds 10
file-snapshot tests to lock that contract for future refactors.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replaces three unwrap-optional helpers + a while-loop with a single
`unwrapOptional(t, { deep })`. Extracts the two `toKebabCase` flavors into
`.typedoc/slug.mjs` — `toFileSlug` (method filenames) and `toUrlSlug` (page URLs)
intentionally differ on acronyms, so the module exports both rather than unifying.

Also adds the snapshot dir to `.prettierignore`: lint-staged was silently
transforming the committed snapshots after `vitest run` passed, leaving them out of
sync with the raw output `extract-methods.mjs` writes. Regenerates them.

Output is byte-identical to the pre-refactor baseline (`diff -r`, 695/695 files).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
`clerkParametersTable` now joins flattened parent.child names with `?.` when
the parent is optional and `.` when required, mirroring how the property
would be accessed at runtime. `nestedParameterRowsFromDocumentedProperties`
applies the same rule. With the theme correct, the regex post-process in
`formatMethodParametersTable` (reorder + blanket `.` → `?.` rename) is no
longer needed — removed (-116 LOC), along with `appendMarkdownTableRows`.

Fixes 8 files where the old blanket rule was wrong in one direction or
the other:

- `shared/clerk/methods/handle-email-link-verification.mdx`: parent
  `params` is required, children now render as `params.foo` (was
  `params?.foo`).
- `backend/get-auth-fn.mdx`, `backend/get-auth-fn-no-request.mdx`,
  `nextjs/current-user.mdx`, `shared/api-keys-namespace.mdx`,
  `shared/custom-navigation.mdx`, `shared/get-memberships.mdx`,
  `shared/on-event-listener.mdx`: parent is optional, children now
  render as `parent?.foo` (was `parent.foo`).

Adds a snapshot for `handle-email-link-verification.mdx` to lock in the
required-parent rendering.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 22, 2026

🦋 Changeset detected

Latest commit: 3f45eb5

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 0 packages

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel
Copy link
Copy Markdown

vercel Bot commented May 22, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
clerk-js-sandbox Ready Ready Preview, Comment May 28, 2026 3:12am

Request Review

@alexisintech alexisintech marked this pull request as draft May 22, 2026 23:50
@alexisintech alexisintech changed the title refactor(typedoc): inline extract-methods + tighten parameter rendering refactor(repo): Inline extract-methods + tighten parameter rendering May 23, 2026
alexisintech and others added 2 commits May 22, 2026 17:53
`custom-theme.mjs` and `extract-methods.mjs` were reaching into
`node_modules/typedoc-plugin-markdown/dist/libs/...` for `backTicks`, `heading`,
`htmlTable`, `table`, `removeLineBreaks`, and the `TypeDeclarationVisibility`
enum — none of which the plugin exports publicly. That coupling breaks on any
dependency update.

Inlines the five utilities (plus the `escapeChars` / `formatTableCell`
helpers they call) into `.typedoc/markdown-helpers.mjs`, and replaces the
enum check with the underlying string literal (`'compact'`). Generated
output is byte-identical to the upstream behavior (`diff -r` shows zero
deltas beyond the unrelated step-4 changes; 16 snapshot tests pass).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…on/generic arms

Three branches of `resolveDeclarationWithObjectMembers` duplicated the
same shape: iterate each arm's children, filter to `Property`, dedupe by
name into a `Map`, and return a sorted list. Each branch also wrapped
that list in a synthetic `DeclarationReflection` (`__intersectionMerged`
/ `__unionMerged` / `__referenceMerged`) just so callers could read
`.children`.

Extracts `mergePropertyArms(arms, options)` for the shared logic. Union
arms pass `{ skipNever: true, pickBetter: true }` to drop `prop?: never`
discriminators and prefer the more-documented branch on name collisions;
intersection and generic-instantiation arms use the default "later arm
wins" overwrite.

`resolveDeclarationWithObjectMembers` now returns
`DeclarationReflection[] | undefined` directly, removing the fake
holders. Callers (`nestedParameterRowsFromDocumentedProperties`,
`resolveNominalObjectTypeForSingleParam`,
`trySingleNominalParameterTypeSection`,
`processExtractMethodsNamespace`) consume the array directly. Generated
output is byte-identical to the prior commit (`diff -rq` shows zero
deltas across 695 files; 16 snapshot tests pass).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- drop unused runtime `MarkdownTheme` import; use JSDoc-only `import('typedoc-plugin-markdown').MarkdownTheme` in the cast
- pre-write job body is sync (`fs.mkdirSync`/`fs.writeFileSync`); drop `async` to satisfy `require-await`
- brace single-line `if (...) return false;` for `curly`
- autofix import order

Output verified byte-identical via `pnpm typedoc:generate:skip-build` + `diff -rq`; `.typedoc` vitest still 16/16.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@alexisintech alexisintech marked this pull request as ready for review May 27, 2026 22:05
manovotny added a commit that referenced this pull request May 28, 2026
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Hoist `unwrapOptional` into shared `.typedoc/type-utils.mjs`; drop the
  duplicate `unwrapOptionalType` from `custom-theme.mjs`.
- `formatTypeScriptSignature`: use the bare last segment for dotted method
  names so the code fence is valid TS (`function sendCode(...)` instead of
  `function emailCode.sendCode(...)`). Heading still shows the qualified
  name. Snapshot refreshed.
- Add a description to `// @ts-check` in the two new helper files to
  satisfy `@typescript-eslint/ban-ts-comment`.
- Add empty changeset per AGENTS.md.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@manovotny
Copy link
Copy Markdown
Contributor

Pushed some changes directly in 3f45eb5.

  • Hoisted unwrapOptional into .typedoc/type-utils.mjs and dropped the duplicate unwrapOptionalType from custom-theme.mjs.
  • formatTypeScriptSignature now uses the bare last segment for dotted method names (function sendCode(...) instead of function emailCode.sendCode(...), which wasn't valid TS). Heading still shows the qualified name. Snapshot refreshed.
  • Added a description after // @ts-check in markdown-helpers.mjs and slug.mjs to satisfy @typescript-eslint/ban-ts-comment.
  • Added an empty changeset per AGENTS.md.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants