Skip to content

Commit 809241d

Browse files
committed
refactor how we handle objects with only callable members; introduce @extractMethods tag
1 parent 5f6a6b7 commit 809241d

4 files changed

Lines changed: 126 additions & 263 deletions

File tree

.typedoc/custom-theme.mjs

Lines changed: 8 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -911,21 +911,22 @@ class ClerkMarkdownThemeContext extends MarkdownThemeContext {
911911
return superPartials.referenceType.call(this, model);
912912
},
913913
/**
914+
* On allowlisted reference-object pages, drop function-valued members and `@extractMethods` namespace parents from property tables (they are documented under `methods/`).
915+
* `extract-methods.mjs` reuses this partial for nominal param tables and nested `@extractMethods` docs on the same URL; pass `applyAllowlistedPropertyTableRowFilters: false` so rows are not stripped.
916+
*
914917
* @param {import('typedoc').DeclarationReflection[]} model
915-
* @param {Parameters<typeof superPartials.propertiesTable>[1]} [options]
918+
* @param {Parameters<typeof superPartials.propertiesTable>[1] & { applyAllowlistedPropertyTableRowFilters?: boolean }} [options]
916919
*/
917920
propertiesTable: (model, options) => {
918921
if (!Array.isArray(model)) {
919922
return superPartials.propertiesTable(/** @type {any} */ (model), options);
920923
}
921924

922-
// On allowlisted output pages only, drop function-valued interface/class properties from property tables (property syntax with function types). Other pages unchanged.
923925
const allowlisted = pageMatchesAllowlist(this.page?.url, REFERENCE_OBJECTS_LIST);
924-
const filtered = allowlisted
926+
const applyAllowlistFilters = allowlisted && options?.applyAllowlistedPropertyTableRowFilters !== false;
927+
const filtered = applyAllowlistFilters
925928
? model.filter(
926-
prop =>
927-
!isCallableInterfaceProperty(prop, this.helpers) &&
928-
!isInlineNamespaceFullyExtractedToMethods(prop, this.helpers),
929+
prop => !isCallableInterfaceProperty(prop, this.helpers) && !prop.comment?.hasModifier('@extractMethods'),
929930
)
930931
: model;
931932
return superPartials.propertiesTable(filtered, options);
@@ -1567,96 +1568,6 @@ function isCallableInterfaceProperty(prop, helpers) {
15671568
return isCallablePropertyValueType(t, helpers, new Set());
15681569
}
15691570

1570-
/**
1571-
* Inline object namespace whose **direct** members are each documented under `methods/` (either a callable → method MDX, or `@propertyTableDoc` → nested property table). Omits the parent row from reference-object property tables (e.g. `emailCode`, `emailLink` on `SignInFutureResource`).
1572-
*
1573-
* @param {import('typedoc').DeclarationReflection} prop
1574-
* @param {import('typedoc-plugin-markdown').MarkdownThemeContext['helpers']} helpers
1575-
*/
1576-
function isInlineNamespaceFullyExtractedToMethods(prop, helpers) {
1577-
const t =
1578-
(prop.kind === ReflectionKind.Property || prop.kind === ReflectionKind.Variable) && prop.type
1579-
? prop.type
1580-
: helpers.getDeclarationType(prop);
1581-
let cur = /** @type {import('typedoc').Type | undefined} */ (t);
1582-
while (
1583-
cur &&
1584-
typeof cur === 'object' &&
1585-
/** @type {{ type?: string }} */ (cur).type === 'optional' &&
1586-
'elementType' in cur
1587-
) {
1588-
cur = /** @type {import('typedoc').Type} */ (/** @type {import('typedoc').OptionalType} */ (cur).elementType);
1589-
}
1590-
if (!(cur instanceof ReflectionType)) {
1591-
return false;
1592-
}
1593-
const children = cur.declaration?.children ?? [];
1594-
if (children.length === 0) {
1595-
return false;
1596-
}
1597-
for (const c of children) {
1598-
if (
1599-
c.kind !== ReflectionKind.Property &&
1600-
c.kind !== ReflectionKind.Variable &&
1601-
c.kind !== ReflectionKind.Accessor
1602-
) {
1603-
return false;
1604-
}
1605-
const documentedViaPropertyTable = Boolean(
1606-
/** @type {import('typedoc').DeclarationReflection} */ (c).comment?.getTag?.('@propertyTableDoc'),
1607-
);
1608-
if (!isCallableInterfaceProperty(c, helpers) && !documentedViaPropertyTable) {
1609-
return false;
1610-
}
1611-
}
1612-
return true;
1613-
}
1614-
1615-
/**
1616-
* Inline object type whose **direct** members are exclusively callables (e.g. `emailCode: { sendCode, verifyCode }` in `SignInFutureResource`).
1617-
* Used by extract-methods to decide which namespaces need the mixed-namespace nested callable path.
1618-
*
1619-
* For property-table omission, see {@link isInlineNamespaceFullyExtractedToMethods}.
1620-
*
1621-
* @param {import('typedoc').DeclarationReflection} prop
1622-
* @param {import('typedoc-plugin-markdown').MarkdownThemeContext['helpers']} helpers
1623-
*/
1624-
function isCallableOnlyNamespaceProperty(prop, helpers) {
1625-
const t =
1626-
(prop.kind === ReflectionKind.Property || prop.kind === ReflectionKind.Variable) && prop.type
1627-
? prop.type
1628-
: helpers.getDeclarationType(prop);
1629-
let cur = /** @type {import('typedoc').SomeType | undefined} */ (t);
1630-
while (
1631-
cur &&
1632-
typeof cur === 'object' &&
1633-
/** @type {{ type?: string }} */ (cur).type === 'optional' &&
1634-
'elementType' in cur
1635-
) {
1636-
cur = /** @type {import('typedoc').SomeType} */ (/** @type {import('typedoc').OptionalType} */ (cur).elementType);
1637-
}
1638-
if (!(cur instanceof ReflectionType)) {
1639-
return false;
1640-
}
1641-
const children = cur.declaration?.children ?? [];
1642-
if (children.length === 0) {
1643-
return false;
1644-
}
1645-
for (const c of children) {
1646-
if (
1647-
c.kind !== ReflectionKind.Property &&
1648-
c.kind !== ReflectionKind.Variable &&
1649-
c.kind !== ReflectionKind.Accessor
1650-
) {
1651-
return false;
1652-
}
1653-
if (!isCallableInterfaceProperty(c, helpers)) {
1654-
return false;
1655-
}
1656-
}
1657-
return true;
1658-
}
1659-
16601571
/**
16611572
* True when the property's value type is callable (function type, union/intersection of callables, or reference to a type alias of a function type). Object types with properties (e.g. namespaces) stay false.
16621573
* E.g. `navigate: CustomNavigation` in clerk.ts
@@ -1740,4 +1651,4 @@ function isCallablePropertyValueType(t, helpers, seenReflectionIds) {
17401651
return false;
17411652
}
17421653

1743-
export { isCallableInterfaceProperty, isCallableOnlyNamespaceProperty };
1654+
export { isCallableInterfaceProperty };

0 commit comments

Comments
 (0)