Skip to content

Commit

Permalink
Improve support for --entryPointStrategy Packages (#1977)
Browse files Browse the repository at this point in the history
* improve --entryPointStrategy Packages support
  • Loading branch information
akphi committed Jul 7, 2022
1 parent 1004768 commit 83a2735
Show file tree
Hide file tree
Showing 11 changed files with 267 additions and 37 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Unreleased

### Features

- Improved support for `--entryPointStrategy Packages`. TypeDoc will now load package-specific configurations from `package.json` `typedoc` field. This configuration allows configuring a custom display name (`typedoc.displayName`) field, entry point (`typedoc.entryPoint` - this is equivalent and will override `typedocMain`), and path to a readme file to be rendered at the top of the package page (`typedoc.readmeFile`), #1658.
- The `--includeVersion` option will now be respected by `--entryPointStrategy Packages`. Also, for this combination, missing `version` field in the root `package.json` will not issue a warning.

## v0.23.5 (2022-07-02)

### Features
Expand Down
43 changes: 36 additions & 7 deletions src/lib/converter/converter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { ProjectReflection, ReflectionKind, SomeType } from "../models/index";
import { Context } from "./context";
import { ConverterComponent } from "./components";
import { Component, ChildableComponent } from "../utils/component";
import { BindOption } from "../utils";
import { BindOption, MinimalSourceFile, readFile } from "../utils";
import { convertType } from "./types";
import { ConverterEvents } from "./converter-events";
import { convertSymbol } from "./symbols";
Expand All @@ -15,6 +15,8 @@ import { hasAllFlags, hasAnyFlag } from "../utils/enum";
import type { DocumentationEntryPoint } from "../utils/entry-point";
import { CommentParserConfig, getComment } from "./comments";
import type { CommentStyle } from "../utils/options/declaration";
import { parseComment } from "./comments/parser";
import { lexCommentString } from "./comments/rawLexer";

/**
* Compiles source files using TypeScript and converts compiler symbols to reflections.
Expand Down Expand Up @@ -201,9 +203,8 @@ export class Converter extends ChildableComponent<
context.setActiveProgram(e.entryPoint.program);
e.context = this.convertExports(
context,
e.entryPoint.sourceFile,
entries.length === 1,
e.entryPoint.displayName
e.entryPoint,
entries.length === 1
);
});
for (const { entryPoint, context } of entries) {
Expand All @@ -218,10 +219,11 @@ export class Converter extends ChildableComponent<

private convertExports(
context: Context,
node: ts.SourceFile,
singleEntryPoint: boolean,
entryName: string
entryPoint: DocumentationEntryPoint,
singleEntryPoint: boolean
) {
const node = entryPoint.sourceFile;
const entryName = entryPoint.displayName;
const symbol = getSymbolForModuleLike(context, node);
let moduleContext: Context;

Expand Down Expand Up @@ -259,6 +261,33 @@ export class Converter extends ChildableComponent<
void 0,
entryName
);

if (entryPoint.readmeFile) {
const readme = readFile(entryPoint.readmeFile);
const comment = parseComment(
lexCommentString(readme),
context.converter.config,
new MinimalSourceFile(readme, entryPoint.readmeFile),
context.logger
);

if (comment.blockTags.length || comment.modifierTags.size) {
const ignored = [
...comment.blockTags.map((tag) => tag.tag),
...comment.modifierTags,
];
context.logger.warn(
`Block and modifier tags will be ignored within the readme:\n\t${ignored.join(
"\n\t"
)}`
);
}

reflection.readme = comment.summary;
}

reflection.version = entryPoint.version;

context.finalizeDeclarationReflection(reflection);
moduleContext = context.withScope(reflection);
}
Expand Down
9 changes: 9 additions & 0 deletions src/lib/converter/plugins/LinkResolverPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import type {
CommentDisplayPart,
InlineTagDisplayPart,
} from "../../models/comments";
import { DeclarationReflection } from "../../models";

const urlPrefix = /^(http|ftp)s?:\/\//;
const brackets = /\[\[([^\]]+)\]\]/g;
Expand Down Expand Up @@ -136,6 +137,14 @@ export class LinkResolverPlugin extends ConverterComponent {
for (const tag of comment.blockTags) {
tag.content = this.processParts(reflection, tag.content, warn);
}

if (reflection instanceof DeclarationReflection && reflection.readme) {
reflection.readme = this.processParts(
reflection,
reflection.readme,
warn
);
}
}

private processParts(
Expand Down
27 changes: 20 additions & 7 deletions src/lib/converter/plugins/PackagePlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import * as FS from "fs";
import { Component, ConverterComponent } from "../components";
import { Converter } from "../converter";
import type { Context } from "../context";
import { BindOption, readFile } from "../../utils";
import { BindOption, EntryPointStrategy, readFile } from "../../utils";
import { getCommonDirectory } from "../../utils/fs";
import { nicePath } from "../../utils/paths";
import { lexCommentString } from "../comments/rawLexer";
Expand All @@ -23,6 +23,9 @@ export class PackagePlugin extends ConverterComponent {
@BindOption("includeVersion")
includeVersion!: boolean;

@BindOption("entryPointStrategy")
entryPointStrategy!: EntryPointStrategy;

/**
* The file name of the found readme.md file.
*/
Expand Down Expand Up @@ -140,9 +143,15 @@ export class PackagePlugin extends ConverterComponent {
if (packageInfo.version) {
project.name = `${project.name} - v${packageInfo.version}`;
} else {
context.logger.warn(
"--includeVersion was specified, but package.json does not specify a version."
);
// since not all monorepo specifies a meaningful version to the main package.json
// this warning should be optional
if (
this.entryPointStrategy !== EntryPointStrategy.Packages
) {
context.logger.warn(
"--includeVersion was specified, but package.json does not specify a version."
);
}
}
}
} else {
Expand All @@ -153,9 +162,13 @@ export class PackagePlugin extends ConverterComponent {
project.name = "Documentation";
}
if (this.includeVersion) {
context.logger.warn(
"--includeVersion was specified, but no package.json was found. Not adding package version to the documentation."
);
// since not all monorepo specifies a meaningful version to the main package.json
// this warning should be optional
if (this.entryPointStrategy !== EntryPointStrategy.Packages) {
context.logger.warn(
"--includeVersion was specified, but no package.json was found. Not adding package version to the documentation."
);
}
}
}
}
Expand Down
11 changes: 11 additions & 0 deletions src/lib/models/reflections/declaration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { ContainerReflection } from "./container";
import type { SignatureReflection } from "./signature";
import type { TypeParameterReflection } from "./type-parameter";
import type { Serializer, JSONOutput } from "../../serialization";
import type { CommentDisplayPart } from "../comments";

/**
* Stores hierarchical type data.
Expand Down Expand Up @@ -129,6 +130,16 @@ export class DeclarationReflection extends ContainerReflection {
*/
typeHierarchy?: DeclarationHierarchy;

/**
* The contents of the readme file of the module when found.
*/
readme?: CommentDisplayPart[];

/**
* The version of the module when found.
*/
version?: string;

override hasGetterOrSetter(): boolean {
return !!this.getSignature || !!this.setSignature;
}
Expand Down
5 changes: 4 additions & 1 deletion src/lib/output/themes/default/partials/header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { hasTypeParameters, join, renderFlags } from "../../lib";
import { JSX } from "../../../../utils";
import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext";
import type { PageEvent } from "../../../events";
import type { Reflection } from "../../../../models";
import { DeclarationReflection, Reflection } from "../../../../models";

export const header = (context: DefaultThemeRenderContext, props: PageEvent<Reflection>) => {
const HeadingLevel = props.model.isProject() ? "h2" : "h1";
Expand All @@ -12,6 +12,9 @@ export const header = (context: DefaultThemeRenderContext, props: PageEvent<Refl
<HeadingLevel>
{props.model.kindString !== "Project" && `${props.model.kindString ?? ""} `}
{props.model.name}
{props.model instanceof DeclarationReflection &&
props.model.version !== undefined &&
` - v${props.model.version}`}
{hasTypeParameters(props.model) && (
<>
{"<"}
Expand Down
23 changes: 17 additions & 6 deletions src/lib/output/themes/default/partials/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { classNames, wbr } from "../../lib";
import { classNames, displayPartsToMarkdown, wbr } from "../../lib";
import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext";
import { JSX } from "../../../../utils";
import type { ContainerReflection, ReflectionCategory } from "../../../../models";
import { JSX, Raw } from "../../../../utils";
import { ContainerReflection, DeclarationReflection, ReflectionCategory, ReflectionKind } from "../../../../models";

function renderCategory({ urlTo, icons }: DefaultThemeRenderContext, item: ReflectionCategory, prependName = "") {
return (
Expand Down Expand Up @@ -67,8 +67,19 @@ export function index(context: DefaultThemeRenderContext, props: ContainerReflec
}

return (
<section class="tsd-panel-group tsd-index-group">
<section class="tsd-panel tsd-index-panel">{content}</section>
</section>
<>
{props instanceof DeclarationReflection &&
props.kind === ReflectionKind.Module &&
props.readme?.length !== 0 && (
<section class="tsd-panel-group">
<section class="tsd-panel tsd-typography">
<Raw html={context.markdown(displayPartsToMarkdown(props.readme || [], context.urlTo))} />
</section>
</section>
)}
<section class="tsd-panel-group tsd-index-group">
<section class="tsd-panel tsd-index-panel">{content}</section>
</section>
</>
);
}
4 changes: 3 additions & 1 deletion src/lib/output/themes/default/partials/navigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,9 @@ function primaryNavigation(context: DefaultThemeRenderContext, props: PageEvent<

return (
<li class={classNames({ current, selected, deprecated: mod.isDeprecated() }, mod.cssClasses)}>
<a href={context.urlTo(mod)}>{wbr(mod.name)}</a>
<a href={context.urlTo(mod)}>
{wbr(`${mod.name}${mod.version !== undefined ? ` - v${mod.version}` : ""}`)}
</a>
{childNav}
</li>
);
Expand Down
36 changes: 34 additions & 2 deletions src/lib/utils/entry-point.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { join, relative, resolve } from "path";
import * as ts from "typescript";
import * as FS from "fs";
import * as Path from "path";
import {
expandPackages,
extractTypedocConfigFromPackageManifest,
getTsEntryPointForPackage,
ignorePackage,
loadPackageManifest,
} from "./package-manifest";
import { createMinimatch, matchesAny } from "./paths";
import { createMinimatch, matchesAny, nicePath } from "./paths";
import type { Logger } from "./loggers";
import type { Options } from "./options";
import { getCommonDirectory, glob, normalizePath } from "./fs";
Expand Down Expand Up @@ -39,8 +41,10 @@ export type EntryPointStrategy =

export interface DocumentationEntryPoint {
displayName: string;
readmeFile?: string;
program: ts.Program;
sourceFile: ts.SourceFile;
version?: string;
}

export function getEntryPoints(
Expand Down Expand Up @@ -321,6 +325,10 @@ function getEntryPointsForPackages(
for (const packagePath of expandedPackages) {
const packageJsonPath = resolve(packagePath, "package.json");
const packageJson = loadPackageManifest(logger, packageJsonPath);
const includeVersion = options.getValue("includeVersion");
const typedocPackageConfig = packageJson
? extractTypedocConfigFromPackageManifest(logger, packageJsonPath)
: undefined;
if (packageJson === undefined) {
logger.error(`Could not load package manifest ${packageJsonPath}`);
return;
Expand Down Expand Up @@ -383,8 +391,32 @@ function getEntryPointsForPackages(
return;
}

if (
includeVersion &&
(!packageJson["version"] ||
typeof packageJson["version"] !== "string")
) {
logger.warn(
`--includeVersion was specified, but "${nicePath(
packageJsonPath
)}" does not properly specify a version.`
);
}

results.push({
displayName: packageJson["name"] as string,
displayName:
typedocPackageConfig?.displayName ??
(packageJson["name"] as string),
version: packageJson["version"] as string | undefined,
readmeFile: typedocPackageConfig?.readmeFile
? Path.resolve(
Path.join(
packageJsonPath,
"..",
typedocPackageConfig?.readmeFile
)
)
: undefined,
program,
sourceFile,
});
Expand Down
Loading

0 comments on commit 83a2735

Please sign in to comment.