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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve support for --entryPointStrategy Packages #1977

Merged
merged 4 commits into from Jul 7, 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
5 changes: 5 additions & 0 deletions CHANGELOG.md
@@ -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
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
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
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
Gerrit0 marked this conversation as resolved.
Show resolved Hide resolved
) {
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
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[];
Gerrit0 marked this conversation as resolved.
Show resolved Hide resolved

/**
* 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
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
@@ -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
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
@@ -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
akphi marked this conversation as resolved.
Show resolved Hide resolved
? Path.resolve(
Path.join(
packageJsonPath,
"..",
typedocPackageConfig?.readmeFile
)
)
: undefined,
program,
sourceFile,
});
Expand Down