mirror of
https://github.com/discordjs/discord.js.git
synced 2024-08-21 07:34:42 +12:00
fix(website): doc links to other packages (#9994)
* fix(website): doc links to other packages * fix: missing parameter * Apply suggestions from code review Co-authored-by: Almeida <almeidx@pm.me> --------- Co-authored-by: Almeida <almeidx@pm.me>
This commit is contained in:
parent
57c414be21
commit
9fdbf0ad65
12 changed files with 53 additions and 19 deletions
|
@ -1,4 +1,4 @@
|
|||
import type { Excerpt } from '@discordjs/api-extractor-model';
|
||||
import type { ApiPackage, Excerpt } from '@discordjs/api-extractor-model';
|
||||
import { ExcerptTokenKind } from '@discordjs/api-extractor-model';
|
||||
import { BuiltinDocumentationLinks } from '~/util/builtinDocumentationLinks';
|
||||
import { DISCORD_API_TYPES_DOCS_URL } from '~/util/constants';
|
||||
|
@ -7,6 +7,11 @@ import { ItemLink } from './ItemLink';
|
|||
import { resolveCanonicalReference, resolveItemURI } from './documentation/util';
|
||||
|
||||
export interface ExcerptTextProps {
|
||||
/**
|
||||
* The package this excerpt is referenced from.
|
||||
*/
|
||||
readonly apiPackage: ApiPackage;
|
||||
|
||||
/**
|
||||
* The tokens to render.
|
||||
*/
|
||||
|
@ -16,7 +21,7 @@ export interface ExcerptTextProps {
|
|||
/**
|
||||
* A component that renders excerpt tokens from an api item.
|
||||
*/
|
||||
export function ExcerptText({ excerpt }: ExcerptTextProps) {
|
||||
export function ExcerptText({ excerpt, apiPackage }: ExcerptTextProps) {
|
||||
return (
|
||||
<span>
|
||||
{excerpt.spannedTokens.map((token, idx) => {
|
||||
|
@ -53,7 +58,9 @@ export function ExcerptText({ excerpt }: ExcerptTextProps) {
|
|||
);
|
||||
}
|
||||
|
||||
const resolved = token.canonicalReference ? resolveCanonicalReference(token.canonicalReference) : null;
|
||||
const resolved = token.canonicalReference
|
||||
? resolveCanonicalReference(token.canonicalReference, apiPackage)
|
||||
: null;
|
||||
|
||||
if (!resolved) {
|
||||
return token.text;
|
||||
|
@ -65,6 +72,7 @@ export function ExcerptText({ excerpt }: ExcerptTextProps) {
|
|||
itemURI={resolveItemURI(resolved.item)}
|
||||
key={`${resolved.item.displayName}-${resolved.item.containerKey}-${idx}`}
|
||||
packageName={resolved.package}
|
||||
version={resolved.version}
|
||||
>
|
||||
{token.text}
|
||||
</ItemLink>
|
||||
|
|
|
@ -20,6 +20,11 @@ export interface ItemLinkProps<Route extends string> extends Omit<LinkProps<Rout
|
|||
|
||||
// TODO: This needs to be properly typed above but monkey-patching it for now.
|
||||
readonly title?: string | undefined;
|
||||
|
||||
/**
|
||||
* The version of the package the item belongs to.
|
||||
*/
|
||||
readonly version?: string | undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -37,7 +42,7 @@ export function ItemLink<Route extends string>(props: PropsWithChildren<ItemLink
|
|||
throw new Error('ItemLink must be used inside a Next.js page. (e.g. /docs/packages/foo/main)');
|
||||
}
|
||||
|
||||
const { itemURI, packageName: pkgName, ...linkProps } = props;
|
||||
const { itemURI, packageName: pkgName, version: pkgVersion, ...linkProps } = props;
|
||||
|
||||
return <Link {...linkProps} href={`/docs/packages/${pkgName ?? packageName}/${version}/${itemURI}`} />;
|
||||
return <Link {...linkProps} href={`/docs/packages/${pkgName ?? packageName}/${pkgVersion ?? version}/${itemURI}`} />;
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ export function ParameterTable({ item }: { readonly item: ApiDocumentedItem & Ap
|
|||
() =>
|
||||
params.map((param) => ({
|
||||
Name: param.isRest ? `...${param.name}` : param.name,
|
||||
Type: <ExcerptText excerpt={param.parameterTypeExcerpt} />,
|
||||
Type: <ExcerptText excerpt={param.parameterTypeExcerpt} apiPackage={item.getAssociatedPackage()!} />,
|
||||
Optional: param.isOptional ? 'Yes' : 'No',
|
||||
Description: param.description ? <TSDoc item={item} tsdoc={param.description} /> : 'None',
|
||||
})),
|
||||
|
|
|
@ -32,7 +32,9 @@ export function Property({
|
|||
>
|
||||
{`${item.displayName}${item.isOptional ? '?' : ''}`}
|
||||
<span>:</span>
|
||||
{item.propertyTypeExcerpt.text ? <ExcerptText excerpt={item.propertyTypeExcerpt} /> : null}
|
||||
{item.propertyTypeExcerpt.text ? (
|
||||
<ExcerptText excerpt={item.propertyTypeExcerpt} apiPackage={item.getAssociatedPackage()!} />
|
||||
) : null}
|
||||
</CodeHeading>
|
||||
</div>
|
||||
{hasSummary || inheritedFrom ? (
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import type { Excerpt } from '@discordjs/api-extractor-model';
|
||||
import type { ApiPackage, Excerpt } from '@discordjs/api-extractor-model';
|
||||
import { ExcerptText } from './ExcerptText';
|
||||
|
||||
export function SignatureText({ excerpt }: { readonly excerpt: Excerpt }) {
|
||||
export function SignatureText({ excerpt, apiPackage }: { readonly apiPackage: ApiPackage; readonly excerpt: Excerpt }) {
|
||||
return (
|
||||
<h4 className="break-all text-lg font-bold font-mono">
|
||||
<ExcerptText excerpt={excerpt} />
|
||||
<ExcerptText excerpt={excerpt} apiPackage={apiPackage} />
|
||||
</h4>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -15,9 +15,9 @@ export function TypeParamTable({ item }: { readonly item: ApiTypeParameterListMi
|
|||
() =>
|
||||
item.typeParameters.map((typeParam) => ({
|
||||
Name: typeParam.name,
|
||||
Constraints: <ExcerptText excerpt={typeParam.constraintExcerpt} />,
|
||||
Constraints: <ExcerptText excerpt={typeParam.constraintExcerpt} apiPackage={item.getAssociatedPackage()!} />,
|
||||
Optional: typeParam.isOptional ? 'Yes' : 'No',
|
||||
Default: <ExcerptText excerpt={typeParam.defaultTypeExcerpt} />,
|
||||
Default: <ExcerptText excerpt={typeParam.defaultTypeExcerpt} apiPackage={item.getAssociatedPackage()!} />,
|
||||
Description: typeParam.tsdocTypeParamBlock ? (
|
||||
<TSDoc item={item} tsdoc={typeParam.tsdocTypeParamBlock.content} />
|
||||
) : (
|
||||
|
|
|
@ -48,7 +48,7 @@ export function HierarchyText({
|
|||
<div className="flex flex-row place-items-center gap-4" key={`${type}-${idx}`}>
|
||||
<h3 className="text-xl font-bold">{type}</h3>
|
||||
<span className="break-all font-mono space-y-2">
|
||||
<ExcerptText excerpt={excerpt} />
|
||||
<ExcerptText excerpt={excerpt} apiPackage={item.getAssociatedPackage()!} />
|
||||
</span>
|
||||
</div>
|
||||
))}
|
||||
|
|
|
@ -52,7 +52,7 @@ export function TSDoc({ item, tsdoc }: { readonly item: ApiItem; readonly tsdoc:
|
|||
|
||||
const declarationReference = item.getAssociatedModel()?.resolveDeclarationReference(codeDestination, item);
|
||||
const foundItem = declarationReference?.resolvedApiItem;
|
||||
const resolved = resolveCanonicalReference(codeDestination);
|
||||
const resolved = resolveCanonicalReference(codeDestination, item.getAssociatedPackage());
|
||||
|
||||
if (!foundItem && !resolved) return null;
|
||||
|
||||
|
@ -84,6 +84,12 @@ export function TSDoc({ item, tsdoc }: { readonly item: ApiItem; readonly tsdoc:
|
|||
itemURI={resolveItemURI(foundItem ?? resolved!.item)}
|
||||
key={idx}
|
||||
packageName={resolved?.package ?? item.getAssociatedPackage()?.displayName.replace('@discordjs/', '')}
|
||||
version={
|
||||
resolved?.package
|
||||
? // eslint-disable-next-line unicorn/better-regex
|
||||
item.getAssociatedPackage()?.dependencies?.[resolved.package]?.replace(/[~^]/, '')
|
||||
: undefined
|
||||
}
|
||||
>
|
||||
{linkText ?? foundItem?.displayName ?? resolved!.item.displayName}
|
||||
</ItemLink>
|
||||
|
|
|
@ -9,6 +9,7 @@ import type {
|
|||
ApiDocumentedItem,
|
||||
ApiParameterListMixin,
|
||||
ApiEvent,
|
||||
ApiPackage,
|
||||
} from '@discordjs/api-extractor-model';
|
||||
import type { DocDeclarationReference } from '@microsoft/tsdoc';
|
||||
import { SelectorKind } from '@microsoft/tsdoc';
|
||||
|
@ -29,6 +30,7 @@ export interface ApiItemLike {
|
|||
interface ResolvedCanonicalReference {
|
||||
item: ApiItemLike;
|
||||
package: string | undefined;
|
||||
version: string | undefined;
|
||||
}
|
||||
|
||||
const kindToMeaning = new Map([
|
||||
|
@ -72,6 +74,7 @@ export function resolveItemURI(item: ApiItemLike): string {
|
|||
|
||||
export function resolveCanonicalReference(
|
||||
canonicalReference: DeclarationReference | DocDeclarationReference,
|
||||
apiPackage: ApiPackage | undefined,
|
||||
): ResolvedCanonicalReference | null {
|
||||
if (
|
||||
'source' in canonicalReference &&
|
||||
|
@ -89,6 +92,8 @@ export function resolveCanonicalReference(
|
|||
canonicalReference.symbol.meaning
|
||||
}|${canonicalReference.symbol.componentPath.component.toString()}`,
|
||||
},
|
||||
// eslint-disable-next-line unicorn/better-regex
|
||||
version: apiPackage?.dependencies?.[canonicalReference.source.packageName]?.replace(/[~^]/, ''),
|
||||
};
|
||||
else if (
|
||||
'memberReferences' in canonicalReference &&
|
||||
|
@ -107,6 +112,8 @@ export function resolveCanonicalReference(
|
|||
.slice(1)
|
||||
.map((member) => ({ kind: member.kind, displayName: member.memberIdentifier!.identifier! })),
|
||||
},
|
||||
// eslint-disable-next-line unicorn/better-regex
|
||||
version: apiPackage?.dependencies?.[canonicalReference.packageName ?? '']?.replace(/[~^]/, ''),
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,9 @@ export function EnumMember({ member }: { readonly member: ApiEnumMember }) {
|
|||
>
|
||||
{member.name}
|
||||
<span>=</span>
|
||||
{member.initializerExcerpt ? <SignatureText excerpt={member.initializerExcerpt} /> : null}
|
||||
{member.initializerExcerpt ? (
|
||||
<SignatureText excerpt={member.initializerExcerpt} apiPackage={member.getAssociatedPackage()!} />
|
||||
) : null}
|
||||
</CodeHeading>
|
||||
{member.tsdocComment ? <TSDoc item={member} tsdoc={member.tsdocComment.summarySection} /> : null}
|
||||
</div>
|
||||
|
|
|
@ -22,7 +22,7 @@ export function MethodHeader({ method }: { readonly method: ApiMethod | ApiMetho
|
|||
>
|
||||
{`${method.name}(${parametersString(method)})`}
|
||||
<span>:</span>
|
||||
<ExcerptText excerpt={method.returnTypeExcerpt} />
|
||||
<ExcerptText excerpt={method.returnTypeExcerpt} apiPackage={method.getAssociatedPackage()!} />
|
||||
</CodeHeading>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1094,6 +1094,10 @@ export class ApiModelGenerator {
|
|||
fileColumn: sourceLocation.sourceFileColumn,
|
||||
});
|
||||
} else if (jsDoc) {
|
||||
if (jsDoc.inherited) {
|
||||
return;
|
||||
}
|
||||
|
||||
const methodOptions = this._mapMethod(jsDoc, parentApiItem.getAssociatedPackage()!.name);
|
||||
if (methodOptions.releaseTag === ReleaseTag.Internal || methodOptions.releaseTag === ReleaseTag.Alpha) {
|
||||
return; // trim out items marked as "@internal" or "@alpha"
|
||||
|
@ -1802,7 +1806,7 @@ export class ApiModelGenerator {
|
|||
text: `${
|
||||
method.scope === 'global'
|
||||
? `export function ${method.name}(`
|
||||
: `${method.access}${method.scope === 'static' ? ' static' : ''} ${method.name}(`
|
||||
: `${method.access ? `${method.access} ` : ''}${method.scope === 'static' ? 'static ' : ''}${method.name}(`
|
||||
}${
|
||||
method.params?.length
|
||||
? `${method.params[0]!.name}${method.params[0]!.nullable || method.params[0]!.optional ? '?' : ''}`
|
||||
|
@ -1853,8 +1857,8 @@ export class ApiModelGenerator {
|
|||
?.map((param) => ` * @param ${param.name} - ${this._fixLinkTags(param.description) ?? ''}\n`)
|
||||
.join('') ?? ''
|
||||
}${
|
||||
method.returns?.length && !Array.isArray(method.returns[0])
|
||||
? ` * @returns ${this._fixLinkTags(method.returns[0]!.description) ?? ''}\n`
|
||||
method.returns?.length && !Array.isArray(method.returns[0]) && method.returns[0]!.description
|
||||
? ` * @returns ${this._fixLinkTags(method.returns[0]!.description) ?? ''}`
|
||||
: ''
|
||||
}${method.examples?.map((example) => ` * @example\n * \`\`\`js\n * ${example}\n * \`\`\`\n`).join('') ?? ''}${
|
||||
method.deprecated
|
||||
|
|
Loading…
Reference in a new issue