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

chore(deps): update doc-dependencies #1110

Merged
merged 5 commits into from Jun 29, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions package.json
Expand Up @@ -127,8 +127,8 @@
"simple-git-hooks": "~2.8.0",
"standard-version": "~9.5.0",
"tsx": "~3.6.0",
"typedoc": "~0.22.17",
"typedoc-plugin-missing-exports": "~0.22.6",
"typedoc": "~0.23.2",
"typedoc-plugin-missing-exports": "~0.23.0",
"typescript": "~4.7.4",
"validator": "~13.7.0",
"vite": "~2.9.13",
Expand Down
25 changes: 12 additions & 13 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

45 changes: 23 additions & 22 deletions scripts/apidoc/parameterDefaults.ts
Expand Up @@ -4,20 +4,16 @@ import type {
EventCallback,
JSONOutput,
ProjectReflection,
SignatureReflection,
} from 'typedoc';
import {
Reflection,
ReflectionKind,
SerializerComponent,
TypeScript,
SignatureReflection,
} from 'typedoc';
import { Reflection, ReflectionKind, TypeScript } from 'typedoc';

const reflectionKindFunctionOrMethod =
ReflectionKind.Function | ReflectionKind.Method;

interface ParameterDefaultsAware extends Reflection {
implementationDefaultParameters: string[];
implementationDefaultParameters: Array<string | undefined>;
}

/**
Expand Down Expand Up @@ -50,7 +46,9 @@ export const parameterDefaultReader: EventCallback = (
* @param value The default value to clean.
* @returns The cleaned default value.
*/
function cleanParameterDefault(value?: string): string {
function cleanParameterDefault(value: string): string;
function cleanParameterDefault(value?: string): string | undefined;
function cleanParameterDefault(value?: string): string | undefined {
if (value == null) {
return undefined;
}
Expand All @@ -61,19 +59,21 @@ function cleanParameterDefault(value?: string): string {
/**
* Serializer that adds the `implementationDefaultParameters` to the JSON output.
*/
export class DefaultParameterAwareSerializer extends SerializerComponent<Reflection> {
serializeGroup(instance: unknown): boolean {
return instance instanceof Reflection;
}
export class DefaultParameterAwareSerializer
implements SerializerComponent<Reflection>
{
readonly priority = 0;

supports(): boolean {
return true;
supports(item: unknown): item is Reflection {
return item instanceof Reflection;
}

toObject(item: Reflection, obj?: object): Partial<JSONOutput.Reflection> {
(obj as ParameterDefaultsAware).implementationDefaultParameters = (
item as ParameterDefaultsAware
).implementationDefaultParameters;
toObject(
item: Reflection,
obj: Partial<JSONOutput.Reflection>
): Partial<JSONOutput.Reflection> {
(obj as unknown as ParameterDefaultsAware).implementationDefaultParameters =
(item as ParameterDefaultsAware).implementationDefaultParameters;
return obj;
}
}
Expand Down Expand Up @@ -101,10 +101,10 @@ export function patchProjectParameterDefaults(
*/
function patchMethodParameterDefaults(method: DeclarationReflection): void {
const signatures = method.signatures;
const signature = signatures[signatures.length - 1];
const signature = signatures?.[signatures.length - 1];
const parameterDefaults = (method as unknown as ParameterDefaultsAware)
.implementationDefaultParameters;
if (parameterDefaults) {
if (signature && parameterDefaults) {
patchSignatureParameterDefaults(signature, parameterDefaults);
}
}
Expand All @@ -117,9 +117,10 @@ function patchMethodParameterDefaults(method: DeclarationReflection): void {
*/
function patchSignatureParameterDefaults(
signature: SignatureReflection,
parameterDefaults: string[]
parameterDefaults: Array<string | undefined>
): void {
const signatureParameters = signature.parameters;
const signatureParameters =
signature.parameters ?? Array.from({ length: parameterDefaults.length });
if (signatureParameters.length !== parameterDefaults.length) {
throw new Error('Unexpected parameter length mismatch');
}
Expand Down
58 changes: 34 additions & 24 deletions scripts/apidoc/signature.ts
Expand Up @@ -16,7 +16,14 @@ import type {
} from '../../docs/.vitepress/components/api-docs/method';
import vitepressConfig from '../../docs/.vitepress/config';
import { faker } from '../../src';
import { formatTypescript, pathOutputDir } from './utils';
import {
extractRawExamples,
extractTagContent,
formatTypescript,
isDeprecated,
joinTagParts,
pathOutputDir,
} from './utils';

export function prettifyMethodName(method: string): string {
return (
Expand All @@ -27,10 +34,7 @@ export function prettifyMethodName(method: string): string {
}

export function toBlock(comment?: Comment): string {
return (
(comment?.shortText.trim() || 'Missing') +
(comment?.text ? `\n\n${comment.text}` : '')
);
return joinTagParts(comment?.summary) || 'Missing';
}

const markdown = createMarkdownRenderer(
Expand Down Expand Up @@ -107,9 +111,9 @@ export function analyzeSignature(

let examples: string;
if (moduleName) {
examples = `faker.${moduleName}.${methodName}${signatureTypeParametersString}(${signatureParametersString}): ${signature.type.toString()}\n`;
examples = `faker.${moduleName}.${methodName}${signatureTypeParametersString}(${signatureParametersString}): ${signature.type?.toString()}\n`;
} else {
examples = `faker.${methodName}${signatureTypeParametersString}(${signatureParametersString}): ${signature.type.toString()}\n`;
examples = `faker.${methodName}${signatureTypeParametersString}(${signatureParametersString}): ${signature.type?.toString()}\n`;
}
faker.seed(0);
if (moduleName) {
Expand All @@ -125,19 +129,13 @@ export function analyzeSignature(
// Ignore the error => hide the example call + result.
}
}
const exampleTags =
signature?.comment?.tags
.filter((tag) => tag.tagName === 'example')
.map((tag) => tag.text.trimEnd()) || [];

const exampleTags = extractRawExamples(signature);
if (exampleTags.length > 0) {
examples += `${exampleTags.join('\n').trim()}\n`;
}

const seeAlsos =
signature.comment?.tags
.filter((t) => t.tagName === 'see')
.map((t) => t.text.trim()) ?? [];
const seeAlsos = extractTagContent('@see', signature);

const prettyMethodName = prettifyMethodName(methodName);
const code = '```';
Expand All @@ -149,7 +147,7 @@ export function analyzeSignature(
parameters: parameters,
returns: typeToText(signature.type),
examples: mdToHtml(`${code}ts\n${examples}${code}`),
deprecated: signature.comment?.hasTag('deprecated') ?? false,
deprecated: isDeprecated(signature),
seeAlsos,
};
}
Expand Down Expand Up @@ -189,8 +187,11 @@ function analyzeParameter(parameter: ParameterReflection): {

function analyzeParameterOptions(
name: string,
parameterType: SomeType
parameterType?: SomeType
): MethodParameter[] {
if (!parameterType) {
return [];
}
if (parameterType.type === 'union') {
return parameterType.types.flatMap((type) =>
analyzeParameterOptions(name, type)
Expand All @@ -214,7 +215,10 @@ function isOptional(parameter: Reflection): boolean {
return parameter.flags.hasFlag(ReflectionFlag.Optional);
}

function typeToText(type_: Type, short = false): string {
function typeToText(type_?: Type, short = false): string {
Shinigami92 marked this conversation as resolved.
Show resolved Hide resolved
if (!type_) {
return '?';
}
const type = type_ as SomeType;
switch (type.type) {
case 'array':
Expand Down Expand Up @@ -257,7 +261,7 @@ function declarationTypeToText(
): string {
switch (declaration.kind) {
case ReflectionKind.Method:
return signatureTypeToText(declaration.signatures[0]);
return signatureTypeToText(declaration.signatures?.[0]);

case ReflectionKind.Property:
return typeToText(declaration.type);
Expand Down Expand Up @@ -285,9 +289,12 @@ function declarationTypeToText(
}
}

function signatureTypeToText(signature: SignatureReflection): string {
function signatureTypeToText(signature?: SignatureReflection): string {
if (!signature) {
return '(???) => ?';
}
return `(${signature.parameters
.map((p) => `${p.name}: ${typeToText(p.type)}`)
?.map((p) => `${p.name}: ${typeToText(p.type)}`)
.join(', ')}) => ${typeToText(signature.type)}`;
}

Expand All @@ -297,11 +304,12 @@ function signatureTypeToText(signature: SignatureReflection): string {
* @param comment The comment to extract the default from.
* @returns The extracted default value.
*/
function extractDefaultFromComment(comment?: Comment): string {
function extractDefaultFromComment(comment?: Comment): string | undefined {
if (!comment) {
return;
}
const text = comment.shortText?.trim();
const summary = comment.summary;
const text = joinTagParts(summary).trim();
if (!text) {
return;
}
Expand All @@ -312,6 +320,8 @@ function extractDefaultFromComment(comment?: Comment): string {
if (result[3].trim()) {
throw new Error(`Found description text after the default value:\n${text}`);
}
comment.shortText = result[1];
summary.splice(summary.length - 2, 2);
const lastSummaryPart = summary[summary.length - 1];
lastSummaryPart.text = lastSummaryPart.text.replace(/[ \n]Defaults to $/, '');
return result[2];
}
55 changes: 54 additions & 1 deletion scripts/apidoc/utils.ts
@@ -1,6 +1,11 @@
import { resolve } from 'node:path';
import type { Options } from 'prettier';
import { format } from 'prettier';
import type {
CommentDisplayPart,
CommentTag,
SignatureReflection,
} from 'typedoc';
import * as TypeDoc from 'typedoc';
import prettierConfig from '../../.prettierrc.cjs';
import {
Expand Down Expand Up @@ -32,7 +37,7 @@ export function newTypeDocApp(): TypeDoc.Application {
parameterDefaultReader
);
// Add to debug json output
app.serializer.addSerializer(new DefaultParameterAwareSerializer(undefined));
app.serializer.addSerializer(new DefaultParameterAwareSerializer());

return app;
}
Expand Down Expand Up @@ -75,3 +80,51 @@ const prettierTypescript: Options = {
...prettierConfig,
parser: 'typescript',
};

/**
* Extracts the text (md) from a jsdoc tag.
*
* @param tag The tag to extract the text from.
* @param signature The signature to extract the text from.
*/
export function extractTagContent(
tag: `@${string}`,
signature?: SignatureReflection
): string[] {
return signature?.comment?.getTags(tag).map(joinTagContent) ?? [];
}

/**
* Extracts the examples from the jsdocs without the surrounding md code block.
*
* @param signature The signature to extract the examples from.
*/
export function extractRawExamples(signature?: SignatureReflection): string[] {
return extractTagContent('@example', signature).map((tag) =>
tag.replace(/^```ts\n/, '').replace(/\n```$/, '')
);
}

/**
* Joins the parts of the given jsdocs tag.
*/
export function joinTagContent(tag: CommentTag): string {
return joinTagParts(tag?.content);
}

export function joinTagParts(parts: CommentDisplayPart[]): string;
export function joinTagParts(parts?: CommentDisplayPart[]): string | undefined;
export function joinTagParts(parts?: CommentDisplayPart[]): string | undefined {
return parts?.map((part) => part.text).join('');
}

/**
* Checks if the given signature is deprecated.
*
* @param signature The signature to check.
*
* @returns `true` if it is deprecated, otherwise `false`.
*/
export function isDeprecated(signature: SignatureReflection): boolean {
return extractTagContent('@deprecated', signature).length > 0;
}