Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(website): misc improvements #9940

Merged
merged 14 commits into from
Nov 13, 2023
Merged
Show file tree
Hide file tree
Changes from 6 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
78 changes: 40 additions & 38 deletions api-extractor.json
Original file line number Diff line number Diff line change
Expand Up @@ -89,48 +89,50 @@
* DEFAULT VALUE: no overrideTsconfig section
*/
"overrideTsconfig": {
// Type Checking
"allowUnreachableCode": false,
"allowUnusedLabels": false,
"exactOptionalPropertyTypes": true,
"noFallthroughCasesInSwitch": true,
"noImplicitOverride": true,
"noImplicitReturns": true,
"noPropertyAccessFromIndexSignature": false,
"noUncheckedIndexedAccess": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"strict": true,
"compilerOptions": {
// Type Checking
"allowUnreachableCode": false,
"allowUnusedLabels": false,
"exactOptionalPropertyTypes": true,
"noFallthroughCasesInSwitch": true,
"noImplicitOverride": true,
"noImplicitReturns": true,
"noPropertyAccessFromIndexSignature": false,
"noUncheckedIndexedAccess": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"strict": true,

// Modules
"allowArbitraryExtensions": false,
"allowImportingTsExtensions": false,
"module": "ESNext",
"moduleResolution": "node",
"resolveJsonModule": true,
"resolvePackageJsonExports": false,
"resolvePackageJsonImports": false,
// Modules
"allowArbitraryExtensions": false,
"allowImportingTsExtensions": false,
"module": "ESNext",
"moduleResolution": "nodenext",
"resolveJsonModule": true,
"resolvePackageJsonExports": false,
"resolvePackageJsonImports": false,

// Emit
"declaration": true,
"declarationMap": true,
"importHelpers": false,
"newLine": "lf",
"noEmitHelpers": true,
"outDir": "dist",
"removeComments": false,
"sourceMap": true,
// Emit
"declaration": true,
"declarationMap": true,
"importHelpers": false,
"newLine": "lf",
"noEmitHelpers": true,
"outDir": "dist",
"removeComments": false,
"sourceMap": true,

// Interop Constraints
"esModuleInterop": false,
"forceConsistentCasingInFileNames": true,
"isolatedModules": true,
// Interop Constraints
"esModuleInterop": false,
"forceConsistentCasingInFileNames": true,
"isolatedModules": true,

// Language and Environment
"experimentalDecorators": true,
"lib": ["ESNext"],
"target": "ES2022",
"useDefineForClassFields": true
// Language and Environment
"experimentalDecorators": true,
"lib": ["ESNext"],
"target": "ES2022",
"useDefineForClassFields": true
}
}
/**
* This option causes the compiler to be invoked with the --skipLibCheck option. This option is not recommended
Expand Down
26 changes: 22 additions & 4 deletions apps/website/src/components/documentation/tsdoc/TSDoc.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { DocNodeKind, StandardTags } from '@microsoft/tsdoc';
import type { Route } from 'next';
import Link from 'next/link';
import { Fragment, useCallback, type ReactNode } from 'react';
import { DocumentationLink } from '~/components/DocumentationLink';
import { BuiltinDocumentationLinks } from '~/util/builtinDocumentationLinks';
import { ItemLink } from '../../ItemLink';
import { SyntaxHighlighter } from '../../SyntaxHighlighter';
import { resolveItemURI } from '../util';
Expand All @@ -12,6 +14,7 @@ import { DefaultValueBlock, DeprecatedBlock, ExampleBlock, RemarksBlock, Returns
export function TSDoc({ item, tsdoc }: { readonly item: ApiItem; readonly tsdoc: DocNode }): JSX.Element {
const createNode = useCallback(
(tsdoc: DocNode, idx?: number): ReactNode => {
// console.log(item.displayName, DocNodeKind[tsdoc.kind]);
switch (tsdoc.kind) {
case DocNodeKind.PlainText:
return (
Expand All @@ -32,10 +35,24 @@ export function TSDoc({ item, tsdoc }: { readonly item: ApiItem; readonly tsdoc:
const { codeDestination, urlDestination, linkText } = tsdoc as DocLinkTag;

if (codeDestination) {
// TODO: Real fix in api-extractor needed
const currentItem = item.getAssociatedPackage();
const foundItem = item.getAssociatedModel()?.resolveDeclarationReference(codeDestination, currentItem)
.resolvedApiItem;
if (
!codeDestination.importPath &&
!codeDestination.packageName &&
codeDestination.memberReferences.length === 1 &&
codeDestination.memberReferences[0]?.memberIdentifier &&
codeDestination.memberReferences[0].memberIdentifier?.identifier in BuiltinDocumentationLinks
) {
const typeName = codeDestination.memberReferences[0]?.memberIdentifier?.identifier;
const href = BuiltinDocumentationLinks[typeName as keyof typeof BuiltinDocumentationLinks];
return (
<DocumentationLink key={`${typeName}-${idx}`} href={href}>
{typeName}
</DocumentationLink>
);
}

const declarationReference = item.getAssociatedModel()?.resolveDeclarationReference(codeDestination, item);
const foundItem = declarationReference.resolvedApiItem;

if (!foundItem) return null;

Expand All @@ -44,6 +61,7 @@ export function TSDoc({ item, tsdoc }: { readonly item: ApiItem; readonly tsdoc:
className="rounded font-mono text-blurple outline-none focus:ring focus:ring-width-2 focus:ring-blurple"
itemURI={resolveItemURI(foundItem)}
key={idx}
packageName={item.getAssociatedPackage()?.displayName.replace('@discordjs/', '')}
>
{linkText ?? foundItem.displayName}
</ItemLink>
Expand Down
4 changes: 2 additions & 2 deletions packages/api-extractor/config/api-extractor.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@

"apiReport": {
"enabled": true,
"reportFolder": "../../../common/reviews/api"
"reportFolder": "<projectFolder>/docs/review"
},

"docModel": {
"enabled": true,
"apiJsonFilePath": "../../../common/temp/api/<unscopedPackageName>.api.json"
"apiJsonFilePath": "<projectFolder>/docs/<unscopedPackageName>.api.json"
},

"dtsRollup": {
Expand Down
2 changes: 1 addition & 1 deletion packages/api-extractor/src/collector/Collector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import { ReleaseTag } from '@discordjs/api-extractor-model';
import * as tsdoc from '@microsoft/tsdoc';
import { PackageJsonLookup, Sort, InternalError } from '@rushstack/node-core-library';
import * as ts from 'typescript';
import ts from 'typescript';
import { PackageDocComment } from '../aedoc/PackageDocComment.js';
import type { AstDeclaration } from '../analyzer/AstDeclaration.js';
import type { AstEntity } from '../analyzer/AstEntity.js';
Expand Down
27 changes: 15 additions & 12 deletions packages/api-extractor/src/generators/ApiModelGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ import {
Navigation,
} from '@discordjs/api-extractor-model';
import type * as tsdoc from '@microsoft/tsdoc';
import { TSDocParser } from '@microsoft/tsdoc';
import { DeclarationReference } from '@microsoft/tsdoc/lib-commonjs/beta/DeclarationReference.js';
import { JsonFile, Path } from '@rushstack/node-core-library';
import * as ts from 'typescript';
Expand Down Expand Up @@ -220,12 +219,16 @@ export class ApiModelGenerator {

private readonly _apiModel: ApiModel;

private readonly _tsDocParser: tsdoc.TSDocParser;

private readonly _referenceGenerator: DeclarationReferenceGenerator;

public constructor(collector: Collector) {
this._collector = collector;
this._apiModel = new ApiModel();
this._referenceGenerator = new DeclarationReferenceGenerator(collector);
// @ts-expect-error we reuse the private tsdocParser from collector here
this._tsDocParser = collector._tsdocParser;
}

public get apiModel(): ApiModel {
Expand Down Expand Up @@ -500,7 +503,7 @@ export class ApiModelGenerator {
const excerptTokens: IExcerptToken[] = this._buildExcerptTokens(astDeclaration, nodesToCapture);
const apiItemMetadata: ApiItemMetadata = this._collector.fetchApiItemMetadata(astDeclaration);
const docComment: tsdoc.DocComment | undefined = parent?.construct
? new TSDocParser().parseString(
? this._tsDocParser.parseString(
`/*+\n * ${fixLinkTags(parent.construct.description)}\n${
parent.construct.params
?.map((param) => ` * @param ${param.name} - ${fixLinkTags(param.description)}\n`)
Expand Down Expand Up @@ -586,7 +589,7 @@ export class ApiModelGenerator {
const excerptTokens: IExcerptToken[] = this._buildExcerptTokens(astDeclaration, nodesToCapture);
const apiItemMetadata: ApiItemMetadata = this._collector.fetchApiItemMetadata(astDeclaration);
const docComment: tsdoc.DocComment | undefined = jsDoc
? new TSDocParser().parseString(
? this._tsDocParser.parseString(
`/**\n * ${fixLinkTags(jsDoc.description)}\n${jsDoc.see?.map((see) => ` * @see ${see}\n`).join('') ?? ''}${
jsDoc.deprecated
? ` * @deprecated ${
Expand Down Expand Up @@ -658,7 +661,7 @@ export class ApiModelGenerator {
const excerptTokens: IExcerptToken[] = this._buildExcerptTokens(astDeclaration, nodesToCapture);
const apiItemMetadata: ApiItemMetadata = this._collector.fetchApiItemMetadata(astDeclaration);
const docComment: tsdoc.DocComment | undefined = parent?.construct
? new TSDocParser().parseString(
? this._tsDocParser.parseString(
`/*+\n * ${fixLinkTags(parent.construct.description)}\n${
parent.construct.params
?.map((param) => ` * @param ${param.name} - ${fixLinkTags(param.description)}\n`)
Expand Down Expand Up @@ -789,7 +792,7 @@ export class ApiModelGenerator {
const excerptTokens: IExcerptToken[] = this._buildExcerptTokens(astDeclaration, nodesToCapture);
const apiItemMetadata: ApiItemMetadata = this._collector.fetchApiItemMetadata(astDeclaration);
const docComment: tsdoc.DocComment | undefined = jsDoc
? new TSDocParser().parseString(
? this._tsDocParser.parseString(
`/**\n * ${fixLinkTags(jsDoc.description)}\n${
jsDoc.params?.map((param) => ` * @param ${param.name} - ${fixLinkTags(param.description)}\n`).join('') ??
''
Expand Down Expand Up @@ -916,7 +919,7 @@ export class ApiModelGenerator {
const excerptTokens: IExcerptToken[] = this._buildExcerptTokens(astDeclaration, nodesToCapture);
const apiItemMetadata: ApiItemMetadata = this._collector.fetchApiItemMetadata(astDeclaration);
const docComment: tsdoc.DocComment | undefined = jsDoc
? new TSDocParser().parseString(
? this._tsDocParser.parseString(
`/**\n * ${fixLinkTags(jsDoc.description)}\n${jsDoc.see?.map((see) => ` * @see ${see}\n`).join('') ?? ''}${
jsDoc.deprecated
? ` * @deprecated ${
Expand Down Expand Up @@ -980,7 +983,7 @@ export class ApiModelGenerator {
const excerptTokens: IExcerptToken[] = this._buildExcerptTokens(astDeclaration, nodesToCapture);
const apiItemMetadata: ApiItemMetadata = this._collector.fetchApiItemMetadata(astDeclaration);
const docComment: tsdoc.DocComment | undefined = jsDoc
? new TSDocParser().parseString(
? this._tsDocParser.parseString(
`/**\n * ${fixLinkTags(jsDoc.description)}\n${
jsDoc.params?.map((param) => ` * @param ${param.name} - ${fixLinkTags(param.description)}\n`).join('') ??
''
Expand Down Expand Up @@ -1058,7 +1061,7 @@ export class ApiModelGenerator {
const excerptTokens: IExcerptToken[] = this._buildExcerptTokens(astDeclaration, nodesToCapture);
const apiItemMetadata: ApiItemMetadata = this._collector.fetchApiItemMetadata(astDeclaration);
const docComment: tsdoc.DocComment | undefined = jsDoc
? new TSDocParser().parseString(
? this._tsDocParser.parseString(
`/**\n * ${fixLinkTags(jsDoc.description)}\n${
jsDoc.params?.map((param) => ` * @param ${param.name} - ${fixLinkTags(param.description)}\n`).join('') ??
''
Expand Down Expand Up @@ -1166,7 +1169,7 @@ export class ApiModelGenerator {
const excerptTokens: IExcerptToken[] = this._buildExcerptTokens(astDeclaration, nodesToCapture);
const apiItemMetadata: ApiItemMetadata = this._collector.fetchApiItemMetadata(astDeclaration);
const docComment: tsdoc.DocComment | undefined = jsDoc
? new TSDocParser().parseString(
? this._tsDocParser.parseString(
`/**\n * ${fixLinkTags(jsDoc.description)}\n${
'see' in jsDoc ? jsDoc.see.map((see) => ` * @see ${see}\n`).join('') : ''
}${'readonly' in jsDoc && jsDoc.readonly ? ' * @readonly\n' : ''}${
Expand Down Expand Up @@ -1229,7 +1232,7 @@ export class ApiModelGenerator {
const excerptTokens: IExcerptToken[] = this._buildExcerptTokens(astDeclaration, nodesToCapture);
const apiItemMetadata: ApiItemMetadata = this._collector.fetchApiItemMetadata(astDeclaration);
const docComment: tsdoc.DocComment | undefined = jsDoc
? new TSDocParser().parseString(
? this._tsDocParser.parseString(
`/**\n * ${fixLinkTags(jsDoc.description)}\n${
'see' in jsDoc ? jsDoc.see.map((see) => ` * @see ${see}\n`).join('') : ''
}${'readonly' in jsDoc && jsDoc.readonly ? ' * @readonly\n' : ''}${
Expand Down Expand Up @@ -1290,7 +1293,7 @@ export class ApiModelGenerator {
const excerptTokens: IExcerptToken[] = this._buildExcerptTokens(astDeclaration, nodesToCapture);
const apiItemMetadata: ApiItemMetadata = this._collector.fetchApiItemMetadata(astDeclaration);
const docComment: tsdoc.DocComment | undefined = jsDoc
? new TSDocParser().parseString(
? this._tsDocParser.parseString(
`/**\n * ${fixLinkTags(jsDoc.description) ?? ''}\n${
'params' in jsDoc
? jsDoc.params.map((param) => ` * @param ${param.name} - ${fixLinkTags(param.description)}\n`).join('')
Expand Down Expand Up @@ -1425,7 +1428,7 @@ export class ApiModelGenerator {
});
}

const docComment: tsdoc.DocComment | undefined = new TSDocParser().parseString(
const docComment: tsdoc.DocComment | undefined = this._tsDocParser.parseString(
`/**\n * ${fixLinkTags(jsDoc.description)}\n${
jsDoc.params?.map((param) => ` * @param ${param.name} - ${fixLinkTags(param.description)}\n`).join('') ?? ''
}${'see' in jsDoc ? jsDoc.see.map((see) => ` * @see ${see}\n`).join('') : ''}${
Expand Down
27 changes: 21 additions & 6 deletions packages/api-extractor/src/generators/ExcerptBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ export class ExcerptBuilder {
return { startIndex: 0, endIndex: 0, typeParameters: [] };
}

public static isPrimitiveKeyword(node: ts.Node): boolean {
private static _isPrimitiveKeyword(node: ts.Node): boolean {
switch (node.kind) {
case ts.SyntaxKind.AnyKeyword:
case ts.SyntaxKind.BigIntKeyword:
Expand All @@ -156,6 +156,15 @@ export class ExcerptBuilder {
}
}

private static _isRedundantBarAfterColon(span: Span) {
return (
span.kind === ts.SyntaxKind.BarToken &&
span.previousSibling === undefined &&
(span.parent?.parent?.previousSibling?.kind === ts.SyntaxKind.LessThanToken ||
span.parent?.parent?.previousSibling?.kind === ts.SyntaxKind.ColonToken)
);
}

private static _buildSpan(excerptTokens: IExcerptToken[], span: Span, state: IBuildSpanState): boolean {
if (span.kind === ts.SyntaxKind.JSDocComment) {
// Discard any comments
Expand All @@ -174,21 +183,21 @@ export class ExcerptBuilder {
if (span.prefix) {
let canonicalReference: DeclarationReference | undefined;

if (span.kind === ts.SyntaxKind.Identifier) {
const name: ts.Identifier = span.node as ts.Identifier;
if (ts.isIdentifier(span.node)) {
const name: ts.Identifier = span.node;
canonicalReference = state.referenceGenerator.getDeclarationReferenceForIdentifier(name);
}

if (canonicalReference) {
ExcerptBuilder._appendToken(excerptTokens, ExcerptTokenKind.Reference, span.prefix, canonicalReference);
} else if (
ExcerptBuilder.isPrimitiveKeyword(span.node) ||
(span.node.kind === ts.SyntaxKind.Identifier &&
ExcerptBuilder._isPrimitiveKeyword(span.node) ||
(ts.isIdentifier(span.node) &&
((ts.isTypeReferenceNode(span.node.parent) && span.node.parent.typeName === span.node) ||
(ts.isTypeParameterDeclaration(span.node.parent) && span.node.parent.name === span.node)))
) {
ExcerptBuilder._appendToken(excerptTokens, ExcerptTokenKind.Reference, span.prefix);
} else {
} else if (!ExcerptBuilder._isRedundantBarAfterColon(span)) {
ExcerptBuilder._appendToken(excerptTokens, ExcerptTokenKind.Content, span.prefix);
}

Expand Down Expand Up @@ -313,6 +322,12 @@ export class ExcerptBuilder {
!startOrEndIndices.has(currentIndex)
) {
prevToken.text += currentToken.text;
// Remove BarTokens from excerpts if they immediately follow a LessThanToken, e.g. `Promise< | Something>`
// would become `Promise<Something>`
if (/<\s*\|/.test(prevToken.text)) {
prevToken.text = prevToken.text.replace(/<\s*\|\s*/, '<');
}

mergeCount = 1;
} else {
// Otherwise, no merging can occur here. Continue to the next index.
Expand Down
Loading
Loading