typedoc 0.28.6 → 0.28.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +1 -1
- package/dist/lib/converter/comments/blockLexer.d.ts +2 -1
- package/dist/lib/converter/comments/blockLexer.js +6 -5
- package/dist/lib/converter/comments/discovery.js +7 -1
- package/dist/lib/converter/comments/index.d.ts +20 -5
- package/dist/lib/converter/comments/index.js +26 -23
- package/dist/lib/converter/comments/lineLexer.js +1 -1
- package/dist/lib/converter/comments/linkResolver.d.ts +2 -2
- package/dist/lib/converter/comments/linkResolver.js +53 -10
- package/dist/lib/converter/comments/parser.d.ts +2 -2
- package/dist/lib/converter/comments/parser.js +6 -6
- package/dist/lib/converter/comments/rawLexer.js +1 -1
- package/dist/lib/converter/comments/textParser.js +93 -19
- package/dist/lib/converter/context.d.ts +10 -0
- package/dist/lib/converter/context.js +30 -10
- package/dist/lib/converter/converter.d.ts +3 -1
- package/dist/lib/converter/converter.js +6 -3
- package/dist/lib/converter/factories/signature.js +1 -2
- package/dist/lib/converter/factories/symbol-id.d.ts +1 -1
- package/dist/lib/converter/factories/symbol-id.js +2 -1
- package/dist/lib/converter/jsdoc.js +1 -2
- package/dist/lib/converter/plugins/CategoryPlugin.d.ts +3 -2
- package/dist/lib/converter/plugins/CategoryPlugin.js +15 -3
- package/dist/lib/converter/plugins/GroupPlugin.d.ts +2 -1
- package/dist/lib/converter/plugins/GroupPlugin.js +23 -9
- package/dist/lib/converter/plugins/ImplementsPlugin.js +49 -11
- package/dist/lib/converter/plugins/LinkResolverPlugin.d.ts +1 -2
- package/dist/lib/converter/plugins/LinkResolverPlugin.js +1 -55
- package/dist/lib/converter/types.js +2 -3
- package/dist/lib/converter/utils/repository.js +1 -1
- package/dist/lib/internationalization/internationalization.js +1 -1
- package/dist/lib/internationalization/locales/en.cjs +4 -1
- package/dist/lib/internationalization/locales/en.d.cts +4 -1
- package/dist/lib/models/Comment.js +1 -1
- package/dist/lib/models/ContainerReflection.d.ts +1 -0
- package/dist/lib/models/ContainerReflection.js +3 -0
- package/dist/lib/models/Reflection.d.ts +2 -0
- package/dist/lib/models/Reflection.js +3 -0
- package/dist/lib/output/themes/default/partials/moduleReflection.js +1 -1
- package/dist/lib/output/themes/default/partials/navigation.js +1 -1
- package/dist/lib/output/themes/default/templates/hierarchy.js +1 -1
- package/dist/lib/serialization/schema.d.ts +1 -1
- package/dist/lib/utils/options/declaration.d.ts +17 -9
- package/dist/lib/utils/options/declaration.js +52 -31
- package/dist/lib/utils/options/readers/arguments.js +2 -0
- package/dist/lib/utils/options/sources/typedoc.js +2 -5
- package/dist/lib/utils/options/tsdoc-defaults.d.ts +1 -1
- package/dist/lib/utils/options/tsdoc-defaults.js +1 -0
- package/dist/lib/utils/plugins.d.ts +2 -1
- package/dist/lib/utils/plugins.js +26 -17
- package/dist/lib/utils/sort.d.ts +2 -1
- package/dist/lib/utils/sort.js +4 -2
- package/dist/lib/utils-common/array.d.ts +1 -2
- package/dist/lib/utils-common/array.js +0 -7
- package/dist/lib/utils-common/jsx.elements.d.ts +1 -1
- package/dist/lib/utils-common/jsx.js +7 -6
- package/dist/lib/utils-common/map.d.ts +1 -1
- package/dist/lib/utils-common/path.d.ts +6 -0
- package/dist/lib/utils-common/validation.js +1 -1
- package/dist/lib/validation/links.js +0 -3
- package/package.json +12 -12
- package/static/style.css +2 -9
- package/tsdoc.json +4 -0
package/dist/index.d.ts
CHANGED
|
@@ -41,7 +41,7 @@ export type { Icons, NavigationElement, PageDefinition, PageHeading, RendererEve
|
|
|
41
41
|
export { Outputs } from "./lib/output/output.js";
|
|
42
42
|
export { ArgumentsReader, CommentStyle, EntryPointStrategy, normalizePath, Option, OptionDefaults, Options, PackageJsonReader, ParameterHint, ParameterType, TSConfigReader, TypeDocReader, ValidatingFileRegistry, } from "./lib/utils/index.js";
|
|
43
43
|
export type { ArrayDeclarationOption, BooleanDeclarationOption, DeclarationOption, DeclarationOptionBase, DeclarationOptionToOptionType, DocumentationEntryPoint, FancyConsoleLogger, FlagsDeclarationOption, JsDocCompatibility, KeyToDeclaration, ManuallyValidatedOption, MapDeclarationOption, MixedDeclarationOption, NumberDeclarationOption, ObjectDeclarationOption, OptionsReader, OutputSpecification, ParameterTypeToOptionTypeMap, SortStrategy, StringDeclarationOption, TypeDocOptionMap, TypeDocOptions, TypeDocOptionValues, ValidationOptions, } from "./lib/utils/index.js";
|
|
44
|
-
export { type ComponentPath, ConsoleLogger, type DeclarationReference, type EnumKeys, EventDispatcher, EventHooks, type GlobString, i18n, JSX, Logger, LogLevel, type Meaning, type MeaningKeyword, type MinimalNode, MinimalSourceFile, type NormalizedPath, type NormalizedPathOrModule, type SymbolReference, type TranslatedString, translateTagName, } from "#utils";
|
|
44
|
+
export { type ComponentPath, ConsoleLogger, type DeclarationReference, type EnumKeys, EventDispatcher, EventHooks, type GlobString, i18n, JSX, Logger, LogLevel, type Meaning, type MeaningKeyword, type MinimalNode, MinimalSourceFile, type NormalizedPath, type NormalizedPathOrModule, type NormalizedPathOrModuleOrFunction, type SymbolReference, type TranslatedString, translateTagName, } from "#utils";
|
|
45
45
|
export { type Deserializable, Deserializer, type DeserializerComponent, JSONOutput, SerializeEvent, Serializer, type SerializerComponent, type SerializerEvents, } from "./lib/serialization/index.js";
|
|
46
46
|
export * as Internationalization from "./lib/internationalization/index.js";
|
|
47
47
|
export type { TranslatableStrings } from "./lib/internationalization/internationalization.js";
|
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
import ts from "typescript";
|
|
2
2
|
import { type Token } from "./lexer.js";
|
|
3
|
-
|
|
3
|
+
import type { Context } from "../context.js";
|
|
4
|
+
export declare function lexBlockComment(file: string, pos?: number, end?: number, createSymbolId?: Context["createSymbolId"], jsDoc?: ts.JSDoc | undefined, checker?: ts.TypeChecker | undefined): Generator<Token, undefined, undefined>;
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import ts from "typescript";
|
|
2
2
|
import { TokenSyntaxKind } from "./lexer.js";
|
|
3
3
|
import { resolveAliasedSymbol } from "../utils/symbols.js";
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
export function* lexBlockComment(file, pos = 0, end = file.length, createSymbolId = () => {
|
|
5
|
+
throw new Error("unreachable");
|
|
6
|
+
}, jsDoc = undefined, checker = undefined) {
|
|
6
7
|
// Wrapper around our real lex function to collapse adjacent text tokens.
|
|
7
8
|
let textToken;
|
|
8
|
-
for (const token of lexBlockComment2(file, pos, end, getLinkTags(jsDoc), checker)) {
|
|
9
|
+
for (const token of lexBlockComment2(file, pos, end, getLinkTags(jsDoc), checker, createSymbolId)) {
|
|
9
10
|
if (token.kind === TokenSyntaxKind.Text) {
|
|
10
11
|
if (textToken) {
|
|
11
12
|
textToken.text += token.text;
|
|
@@ -53,7 +54,7 @@ function getLinkTags(jsDoc) {
|
|
|
53
54
|
}
|
|
54
55
|
return result;
|
|
55
56
|
}
|
|
56
|
-
function* lexBlockComment2(file, pos, end, linkTags, checker) {
|
|
57
|
+
function* lexBlockComment2(file, pos, end, linkTags, checker, createSymbolId) {
|
|
57
58
|
pos += 2; // Leading '/*'
|
|
58
59
|
end -= 2; // Trailing '*/'
|
|
59
60
|
if (pos < end && file[pos] === "*") {
|
|
@@ -208,7 +209,7 @@ function* lexBlockComment2(file, pos, end, linkTags, checker) {
|
|
|
208
209
|
}
|
|
209
210
|
if (lookahead !== pos + 1) {
|
|
210
211
|
while (lookahead < end &&
|
|
211
|
-
/[a-z0-9]/i.test(file[lookahead])) {
|
|
212
|
+
/[a-z0-9-]/i.test(file[lookahead])) {
|
|
212
213
|
lookahead++;
|
|
213
214
|
}
|
|
214
215
|
}
|
|
@@ -78,6 +78,7 @@ const wantedKinds = {
|
|
|
78
78
|
[ReflectionKind.Interface]: [
|
|
79
79
|
ts.SyntaxKind.InterfaceDeclaration,
|
|
80
80
|
ts.SyntaxKind.TypeAliasDeclaration,
|
|
81
|
+
ts.SyntaxKind.ClassDeclaration, // type only exports
|
|
81
82
|
],
|
|
82
83
|
[ReflectionKind.Constructor]: [ts.SyntaxKind.Constructor],
|
|
83
84
|
[ReflectionKind.Property]: variablePropertyKinds,
|
|
@@ -102,7 +103,12 @@ const wantedKinds = {
|
|
|
102
103
|
[ReflectionKind.Accessor]: [ts.SyntaxKind.PropertyDeclaration],
|
|
103
104
|
[ReflectionKind.GetSignature]: [ts.SyntaxKind.GetAccessor],
|
|
104
105
|
[ReflectionKind.SetSignature]: [ts.SyntaxKind.SetAccessor],
|
|
105
|
-
[ReflectionKind.TypeAlias]: [
|
|
106
|
+
[ReflectionKind.TypeAlias]: [
|
|
107
|
+
ts.SyntaxKind.TypeAliasDeclaration,
|
|
108
|
+
ts.SyntaxKind.FunctionDeclaration, // type only exports
|
|
109
|
+
// Intentionally not included to avoid comments being copied for variable/alias combos
|
|
110
|
+
// ts.SyntaxKind.VariableDeclaration,
|
|
111
|
+
],
|
|
106
112
|
[ReflectionKind.Reference]: [
|
|
107
113
|
ts.SyntaxKind.NamespaceExport,
|
|
108
114
|
ts.SyntaxKind.ExportSpecifier,
|
|
@@ -3,6 +3,7 @@ import { Comment, ReflectionKind } from "../../models/index.js";
|
|
|
3
3
|
import type { CommentStyle, JsDocCompatibility } from "../../utils/options/declaration.js";
|
|
4
4
|
import type { FileRegistry } from "../../models/FileRegistry.js";
|
|
5
5
|
import { type Logger } from "#utils";
|
|
6
|
+
import type { Context } from "../context.js";
|
|
6
7
|
export interface CommentParserConfig {
|
|
7
8
|
blockTags: Set<string>;
|
|
8
9
|
inlineTags: Set<string>;
|
|
@@ -12,9 +13,23 @@ export interface CommentParserConfig {
|
|
|
12
13
|
useTsLinkResolution: boolean;
|
|
13
14
|
commentStyle: CommentStyle;
|
|
14
15
|
}
|
|
16
|
+
export interface CommentContext {
|
|
17
|
+
config: CommentParserConfig;
|
|
18
|
+
logger: Logger;
|
|
19
|
+
checker: ts.TypeChecker;
|
|
20
|
+
files: FileRegistry;
|
|
21
|
+
createSymbolId: Context["createSymbolId"];
|
|
22
|
+
}
|
|
23
|
+
export interface CommentContextOptionalChecker {
|
|
24
|
+
config: CommentParserConfig;
|
|
25
|
+
logger: Logger;
|
|
26
|
+
checker?: ts.TypeChecker | undefined;
|
|
27
|
+
files: FileRegistry;
|
|
28
|
+
createSymbolId: Context["createSymbolId"];
|
|
29
|
+
}
|
|
15
30
|
export declare function clearCommentCache(): void;
|
|
16
|
-
export declare function getComment(symbol: ts.Symbol, kind: ReflectionKind,
|
|
17
|
-
export declare function getNodeComment(node: ts.Node, moduleComment: boolean,
|
|
18
|
-
export declare function getFileComment(file: ts.SourceFile,
|
|
19
|
-
export declare function getSignatureComment(declaration: ts.SignatureDeclaration | ts.JSDocSignature,
|
|
20
|
-
export declare function getJsDocComment(declaration: ts.JSDocPropertyLikeTag | ts.JSDocCallbackTag | ts.JSDocTypedefTag | ts.JSDocTemplateTag | ts.JSDocEnumTag,
|
|
31
|
+
export declare function getComment(symbol: ts.Symbol, kind: ReflectionKind, context: CommentContext): Comment | undefined;
|
|
32
|
+
export declare function getNodeComment(node: ts.Node, moduleComment: boolean, context: CommentContext): Comment | undefined;
|
|
33
|
+
export declare function getFileComment(file: ts.SourceFile, context: CommentContext): Comment | undefined;
|
|
34
|
+
export declare function getSignatureComment(declaration: ts.SignatureDeclaration | ts.JSDocSignature, context: CommentContext): Comment | undefined;
|
|
35
|
+
export declare function getJsDocComment(declaration: ts.JSDocPropertyLikeTag | ts.JSDocCallbackTag | ts.JSDocTypedefTag | ts.JSDocTemplateTag | ts.JSDocEnumTag, context: CommentContext): Comment | undefined;
|
|
@@ -21,7 +21,7 @@ export function clearCommentCache() {
|
|
|
21
21
|
commentCache = new WeakMap();
|
|
22
22
|
commentDiscoveryId = 0;
|
|
23
23
|
}
|
|
24
|
-
function getCommentWithCache(discovered,
|
|
24
|
+
function getCommentWithCache(discovered, context) {
|
|
25
25
|
if (!discovered)
|
|
26
26
|
return;
|
|
27
27
|
const { file, ranges, jsDoc } = discovered;
|
|
@@ -34,10 +34,10 @@ function getCommentWithCache(discovered, config, logger, checker, files) {
|
|
|
34
34
|
let comment;
|
|
35
35
|
switch (ranges[0].kind) {
|
|
36
36
|
case ts.SyntaxKind.MultiLineCommentTrivia:
|
|
37
|
-
comment = parseComment(lexBlockComment(file.text, ranges[0].pos, ranges[0].end, jsDoc, checker),
|
|
37
|
+
comment = parseComment(lexBlockComment(file.text, ranges[0].pos, ranges[0].end, context.createSymbolId, jsDoc, context.checker), file, context);
|
|
38
38
|
break;
|
|
39
39
|
case ts.SyntaxKind.SingleLineCommentTrivia:
|
|
40
|
-
comment = parseComment(lexLineComments(file.text, ranges),
|
|
40
|
+
comment = parseComment(lexLineComments(file.text, ranges), file, context);
|
|
41
41
|
break;
|
|
42
42
|
default:
|
|
43
43
|
assertNever(ranges[0].kind);
|
|
@@ -48,8 +48,11 @@ function getCommentWithCache(discovered, config, logger, checker, files) {
|
|
|
48
48
|
commentCache.set(file, cache);
|
|
49
49
|
return comment.clone();
|
|
50
50
|
}
|
|
51
|
-
function getCommentImpl(commentSource,
|
|
52
|
-
const comment = getCommentWithCache(commentSource,
|
|
51
|
+
function getCommentImpl(commentSource, moduleComment, context) {
|
|
52
|
+
const comment = getCommentWithCache(commentSource, {
|
|
53
|
+
...context,
|
|
54
|
+
checker: context.config.useTsLinkResolution ? context.checker : undefined,
|
|
55
|
+
});
|
|
53
56
|
if (comment?.getTag("@import") || comment?.getTag("@license")) {
|
|
54
57
|
return;
|
|
55
58
|
}
|
|
@@ -70,15 +73,15 @@ function getCommentImpl(commentSource, config, logger, moduleComment, checker, f
|
|
|
70
73
|
}
|
|
71
74
|
return comment;
|
|
72
75
|
}
|
|
73
|
-
export function getComment(symbol, kind,
|
|
76
|
+
export function getComment(symbol, kind, context) {
|
|
74
77
|
const declarations = symbol.declarations || [];
|
|
75
78
|
if (declarations.length &&
|
|
76
79
|
declarations.every((d) => jsDocCommentKinds.includes(d.kind))) {
|
|
77
|
-
return getJsDocComment(declarations[0],
|
|
80
|
+
return getJsDocComment(declarations[0], context);
|
|
78
81
|
}
|
|
79
82
|
const sf = declarations.find(ts.isSourceFile);
|
|
80
83
|
if (sf) {
|
|
81
|
-
return getFileComment(sf,
|
|
84
|
+
return getFileComment(sf, context);
|
|
82
85
|
}
|
|
83
86
|
const isModule = declarations.some((decl) => {
|
|
84
87
|
if (ts.isModuleDeclaration(decl) && ts.isStringLiteral(decl.name)) {
|
|
@@ -86,18 +89,18 @@ export function getComment(symbol, kind, config, logger, checker, files) {
|
|
|
86
89
|
}
|
|
87
90
|
return false;
|
|
88
91
|
});
|
|
89
|
-
const comment = getCommentImpl(discoverComment(symbol, kind, logger, config.commentStyle, checker, !config.suppressCommentWarningsInDeclarationFiles),
|
|
92
|
+
const comment = getCommentImpl(discoverComment(symbol, kind, context.logger, context.config.commentStyle, context.checker, !context.config.suppressCommentWarningsInDeclarationFiles), isModule, context);
|
|
90
93
|
if (!comment && kind === ReflectionKind.Property) {
|
|
91
|
-
return getConstructorParamPropertyComment(symbol,
|
|
94
|
+
return getConstructorParamPropertyComment(symbol, context);
|
|
92
95
|
}
|
|
93
96
|
return comment;
|
|
94
97
|
}
|
|
95
|
-
export function getNodeComment(node, moduleComment,
|
|
96
|
-
return getCommentImpl(discoverNodeComment(node, config.commentStyle),
|
|
98
|
+
export function getNodeComment(node, moduleComment, context) {
|
|
99
|
+
return getCommentImpl(discoverNodeComment(node, context.config.commentStyle), moduleComment, context);
|
|
97
100
|
}
|
|
98
|
-
export function getFileComment(file,
|
|
99
|
-
for (const commentSource of discoverFileComments(file, config.commentStyle)) {
|
|
100
|
-
const comment = getCommentWithCache(commentSource,
|
|
101
|
+
export function getFileComment(file, context) {
|
|
102
|
+
for (const commentSource of discoverFileComments(file, context.config.commentStyle)) {
|
|
103
|
+
const comment = getCommentWithCache(commentSource, context);
|
|
101
104
|
if (comment?.getTag("@license") || comment?.getTag("@import")) {
|
|
102
105
|
continue;
|
|
103
106
|
}
|
|
@@ -108,12 +111,12 @@ export function getFileComment(file, config, logger, checker, files) {
|
|
|
108
111
|
return;
|
|
109
112
|
}
|
|
110
113
|
}
|
|
111
|
-
function getConstructorParamPropertyComment(symbol,
|
|
114
|
+
function getConstructorParamPropertyComment(symbol, context) {
|
|
112
115
|
const decl = symbol.declarations?.find(ts.isParameter);
|
|
113
116
|
if (!decl)
|
|
114
117
|
return;
|
|
115
118
|
const ctor = decl.parent;
|
|
116
|
-
const comment = getSignatureComment(ctor,
|
|
119
|
+
const comment = getSignatureComment(ctor, context);
|
|
117
120
|
const paramTag = comment?.getIdentifiedTag(symbol.name, "@param");
|
|
118
121
|
if (paramTag) {
|
|
119
122
|
const result = new Comment(paramTag.content);
|
|
@@ -121,10 +124,10 @@ function getConstructorParamPropertyComment(symbol, config, logger, checker, fil
|
|
|
121
124
|
return result;
|
|
122
125
|
}
|
|
123
126
|
}
|
|
124
|
-
export function getSignatureComment(declaration,
|
|
125
|
-
return getCommentImpl(discoverSignatureComment(declaration, checker, config.commentStyle),
|
|
127
|
+
export function getSignatureComment(declaration, context) {
|
|
128
|
+
return getCommentImpl(discoverSignatureComment(declaration, context.checker, context.config.commentStyle), false, context);
|
|
126
129
|
}
|
|
127
|
-
export function getJsDocComment(declaration,
|
|
130
|
+
export function getJsDocComment(declaration, context) {
|
|
128
131
|
const file = declaration.getSourceFile();
|
|
129
132
|
// First, get the whole comment. We know we'll need all of it.
|
|
130
133
|
let parent = declaration.parent;
|
|
@@ -143,7 +146,7 @@ export function getJsDocComment(declaration, config, logger, checker, files) {
|
|
|
143
146
|
],
|
|
144
147
|
jsDoc: parent,
|
|
145
148
|
inheritedFromParentDeclaration: false,
|
|
146
|
-
},
|
|
149
|
+
}, context);
|
|
147
150
|
// And pull out the tag we actually care about.
|
|
148
151
|
if (ts.isJSDocEnumTag(declaration)) {
|
|
149
152
|
const result = new Comment(comment.getTag("@enum")?.content);
|
|
@@ -156,7 +159,7 @@ export function getJsDocComment(declaration, config, logger, checker, files) {
|
|
|
156
159
|
// We could just put the same comment on everything, but due to how comment parsing works,
|
|
157
160
|
// we'd have to search for any @template with a name starting with the first type parameter's name
|
|
158
161
|
// which feels horribly hacky.
|
|
159
|
-
logger.warn(i18n.multiple_type_parameters_on_template_tag_unsupported(), declaration);
|
|
162
|
+
context.logger.warn(i18n.multiple_type_parameters_on_template_tag_unsupported(), declaration);
|
|
160
163
|
return;
|
|
161
164
|
}
|
|
162
165
|
let name;
|
|
@@ -176,7 +179,7 @@ export function getJsDocComment(declaration, config, logger, checker, files) {
|
|
|
176
179
|
// was a comment attached. If there wasn't, then don't error about failing to find
|
|
177
180
|
// a tag because this is unsupported.
|
|
178
181
|
if (!ts.isJSDocTemplateTag(declaration)) {
|
|
179
|
-
logger.error(i18n.failed_to_find_jsdoc_tag_for_name_0(name), declaration);
|
|
182
|
+
context.logger.error(i18n.failed_to_find_jsdoc_tag_for_name_0(name), declaration);
|
|
180
183
|
}
|
|
181
184
|
}
|
|
182
185
|
else {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type CommentDisplayPart, Reflection, ReflectionSymbolId } from "../../models/index.js";
|
|
2
2
|
import { type DeclarationReference } from "#utils";
|
|
3
3
|
export type ExternalResolveResult = {
|
|
4
4
|
target: string;
|
|
@@ -16,5 +16,5 @@ export type ExternalSymbolResolver = (ref: DeclarationReference, refl: Reflectio
|
|
|
16
16
|
export type LinkResolverOptions = {
|
|
17
17
|
preserveLinkText: boolean;
|
|
18
18
|
};
|
|
19
|
-
export declare function resolveLinks(
|
|
19
|
+
export declare function resolveLinks(reflection: Reflection, externalResolver: ExternalSymbolResolver, options: LinkResolverOptions): void;
|
|
20
20
|
export declare function resolvePartLinks(reflection: Reflection, parts: readonly CommentDisplayPart[], externalResolver: ExternalSymbolResolver, options: LinkResolverOptions): CommentDisplayPart[];
|
|
@@ -1,19 +1,62 @@
|
|
|
1
1
|
import ts from "typescript";
|
|
2
|
-
import {
|
|
2
|
+
import { makeRecursiveVisitor, Reflection, ReflectionKind, ReflectionSymbolId, } from "../../models/index.js";
|
|
3
3
|
import { resolveDeclarationReference } from "./declarationReferenceResolver.js";
|
|
4
4
|
import { maxElementByScore, parseDeclarationReference } from "#utils";
|
|
5
5
|
const urlPrefix = /^(http|ftp)s?:\/\//;
|
|
6
|
-
export function resolveLinks(
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
export function resolveLinks(reflection, externalResolver, options) {
|
|
7
|
+
if (reflection.comment) {
|
|
8
|
+
reflection.comment.summary = resolvePartLinks(reflection, reflection.comment.summary, externalResolver, options);
|
|
9
|
+
for (const tag of reflection.comment.blockTags) {
|
|
10
|
+
tag.content = resolvePartLinks(reflection, tag.content, externalResolver, options);
|
|
11
|
+
}
|
|
10
12
|
}
|
|
11
|
-
if (reflection
|
|
13
|
+
if ((reflection.isDeclaration() || reflection.isProject()) && reflection.readme) {
|
|
12
14
|
reflection.readme = resolvePartLinks(reflection, reflection.readme, externalResolver, options);
|
|
13
15
|
}
|
|
16
|
+
if (reflection.isDeclaration()) {
|
|
17
|
+
reflection.type?.visit(makeRecursiveVisitor({
|
|
18
|
+
union: (type) => {
|
|
19
|
+
type.elementSummaries = type.elementSummaries?.map((parts) => resolvePartLinks(reflection, parts, externalResolver, options));
|
|
20
|
+
},
|
|
21
|
+
}));
|
|
22
|
+
}
|
|
14
23
|
if (reflection.isDocument()) {
|
|
15
24
|
reflection.content = resolvePartLinks(reflection, reflection.content, externalResolver, options);
|
|
16
25
|
}
|
|
26
|
+
if (reflection.isParameter() &&
|
|
27
|
+
reflection.type?.type === "reference" &&
|
|
28
|
+
reflection.type.highlightedProperties) {
|
|
29
|
+
const resolved = new Map(Array.from(reflection.type.highlightedProperties, ([name, parts]) => {
|
|
30
|
+
return [
|
|
31
|
+
name,
|
|
32
|
+
resolvePartLinks(reflection, parts, externalResolver, options),
|
|
33
|
+
];
|
|
34
|
+
}));
|
|
35
|
+
reflection.type.highlightedProperties = resolved;
|
|
36
|
+
}
|
|
37
|
+
if (reflection.isContainer()) {
|
|
38
|
+
if (reflection.groups) {
|
|
39
|
+
for (const group of reflection.groups) {
|
|
40
|
+
if (group.description) {
|
|
41
|
+
group.description = resolvePartLinks(reflection, group.description, externalResolver, options);
|
|
42
|
+
}
|
|
43
|
+
if (group.categories) {
|
|
44
|
+
for (const cat of group.categories) {
|
|
45
|
+
if (cat.description) {
|
|
46
|
+
cat.description = resolvePartLinks(reflection, cat.description, externalResolver, options);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
if (reflection.categories) {
|
|
53
|
+
for (const cat of reflection.categories) {
|
|
54
|
+
if (cat.description) {
|
|
55
|
+
cat.description = resolvePartLinks(reflection, cat.description, externalResolver, options);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
17
60
|
}
|
|
18
61
|
export function resolvePartLinks(reflection, parts, externalResolver, options) {
|
|
19
62
|
return parts.flatMap((part) => processPart(reflection, part, externalResolver, options));
|
|
@@ -48,10 +91,10 @@ function resolveLinkTag(reflection, part, externalResolver, options) {
|
|
|
48
91
|
const tsTargets = reflection.project.getReflectionsFromSymbolId(part.target);
|
|
49
92
|
if (tsTargets.length) {
|
|
50
93
|
// Find the target most likely to have a real url in the generated documentation
|
|
51
|
-
//
|
|
52
|
-
//
|
|
53
|
-
//
|
|
54
|
-
//
|
|
94
|
+
// 4. A direct export (class, interface, variable)
|
|
95
|
+
// 3. A property of a direct export (class/interface property)
|
|
96
|
+
// 2. A property of a type of an export (property on type alias)
|
|
97
|
+
// 1. Whatever the first symbol found was
|
|
55
98
|
target = maxElementByScore(tsTargets, (r) => {
|
|
56
99
|
if (r.kindOf(ReflectionKind.SomeExport)) {
|
|
57
100
|
return 4;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import type { CommentParserConfig } from "./index.js";
|
|
1
|
+
import type { CommentContextOptionalChecker, CommentParserConfig } from "./index.js";
|
|
2
2
|
import { Comment, type CommentDisplayPart } from "../../models/index.js";
|
|
3
3
|
import type { MinimalSourceFile } from "#utils";
|
|
4
4
|
import { type Token } from "./lexer.js";
|
|
5
5
|
import { FileRegistry } from "../../models/FileRegistry.js";
|
|
6
6
|
import { type Logger } from "#utils";
|
|
7
|
-
export declare function parseComment(tokens: Generator<Token, undefined, undefined>,
|
|
7
|
+
export declare function parseComment(tokens: Generator<Token, undefined, undefined>, file: MinimalSourceFile, context: CommentContextOptionalChecker): Comment;
|
|
8
8
|
/**
|
|
9
9
|
* Intended for parsing markdown documents. This only parses code blocks and
|
|
10
10
|
* inline tags outside of code blocks, everything else is text.
|
|
@@ -40,24 +40,24 @@ function makeLookaheadGenerator(gen) {
|
|
|
40
40
|
},
|
|
41
41
|
};
|
|
42
42
|
}
|
|
43
|
-
export function parseComment(tokens,
|
|
43
|
+
export function parseComment(tokens, file, context) {
|
|
44
44
|
const lexer = makeLookaheadGenerator(tokens);
|
|
45
45
|
const tok = lexer.done() || lexer.peek();
|
|
46
46
|
const comment = new Comment();
|
|
47
47
|
comment.sourcePath = file.fileName;
|
|
48
|
-
comment.summary = blockContent(comment, lexer, config, i18n, warningImpl, files);
|
|
48
|
+
comment.summary = blockContent(comment, lexer, context.config, i18n, warningImpl, context.files);
|
|
49
49
|
while (!lexer.done()) {
|
|
50
|
-
comment.blockTags.push(blockTag(comment, lexer, config, i18n, warningImpl, files));
|
|
50
|
+
comment.blockTags.push(blockTag(comment, lexer, context.config, i18n, warningImpl, context.files));
|
|
51
51
|
}
|
|
52
52
|
const tok2 = tok;
|
|
53
|
-
postProcessComment(comment, i18n, () => `${nicePath(file.fileName)}:${file.getLineAndCharacterOfPosition(tok2.pos).line + 1}`, (message) => logger.warn(message));
|
|
53
|
+
postProcessComment(comment, i18n, () => `${nicePath(file.fileName)}:${file.getLineAndCharacterOfPosition(tok2.pos).line + 1}`, (message) => context.logger.warn(message));
|
|
54
54
|
return comment;
|
|
55
55
|
function warningImpl(message, token) {
|
|
56
|
-
if (config.suppressCommentWarningsInDeclarationFiles &&
|
|
56
|
+
if (context.config.suppressCommentWarningsInDeclarationFiles &&
|
|
57
57
|
hasDeclarationFileExtension(file.fileName)) {
|
|
58
58
|
return;
|
|
59
59
|
}
|
|
60
|
-
logger.warn(message, token.pos, file);
|
|
60
|
+
context.logger.warn(message, token.pos, file);
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
63
|
/**
|
|
@@ -85,9 +85,11 @@ export function textContent(sourcePath, token, i18n, warning, outContent, files,
|
|
|
85
85
|
addRef(reference);
|
|
86
86
|
continue;
|
|
87
87
|
}
|
|
88
|
-
const
|
|
89
|
-
if (
|
|
90
|
-
|
|
88
|
+
const tagLinks = checkTagLink(data);
|
|
89
|
+
if (tagLinks.length) {
|
|
90
|
+
for (const tagLink of tagLinks) {
|
|
91
|
+
addRef(tagLink);
|
|
92
|
+
}
|
|
91
93
|
continue;
|
|
92
94
|
}
|
|
93
95
|
const atNewLine = token.text[data.pos] === "\n";
|
|
@@ -221,39 +223,111 @@ function checkReference(data) {
|
|
|
221
223
|
}
|
|
222
224
|
}
|
|
223
225
|
/**
|
|
224
|
-
* Looks for `<a href="./relative"
|
|
226
|
+
* Looks for `<a href="./relative">`, `<img src="./relative">`, and `<source srcset="./relative">`
|
|
225
227
|
*/
|
|
226
228
|
function checkTagLink(data) {
|
|
227
229
|
const { pos, token } = data;
|
|
228
230
|
if (token.text.startsWith("<img ", pos)) {
|
|
229
231
|
data.pos += 4;
|
|
230
|
-
return
|
|
232
|
+
return checkAttributes(data, {
|
|
233
|
+
src: checkAttributeDirectPath,
|
|
234
|
+
srcset: checkAttributeSrcSet,
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
if (token.text.startsWith("<link ", pos)) {
|
|
238
|
+
data.pos += 4;
|
|
239
|
+
return checkAttributes(data, {
|
|
240
|
+
imagesrcset: checkAttributeSrcSet,
|
|
241
|
+
});
|
|
231
242
|
}
|
|
232
243
|
if (token.text.startsWith("<a ", pos)) {
|
|
233
244
|
data.pos += 3;
|
|
234
|
-
return
|
|
245
|
+
return checkAttributes(data, { href: checkAttributeDirectPath });
|
|
235
246
|
}
|
|
247
|
+
if (token.text.startsWith("<source ", pos)) {
|
|
248
|
+
data.pos += 8;
|
|
249
|
+
return checkAttributes(data, {
|
|
250
|
+
src: checkAttributeDirectPath,
|
|
251
|
+
srcset: checkAttributeSrcSet,
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
return [];
|
|
236
255
|
}
|
|
237
|
-
function
|
|
256
|
+
function checkAttributes(data, attributes) {
|
|
257
|
+
const links = [];
|
|
238
258
|
const parser = new HtmlAttributeParser(data.token.text, data.pos);
|
|
239
259
|
while (parser.state !== ParserState.END) {
|
|
240
260
|
if (parser.state === ParserState.BeforeAttributeValue &&
|
|
241
|
-
parser.currentAttributeName
|
|
261
|
+
Object.prototype.hasOwnProperty.call(attributes, parser.currentAttributeName)) {
|
|
242
262
|
parser.step();
|
|
243
|
-
|
|
244
|
-
data.pos = parser.pos;
|
|
245
|
-
const { target, anchor } = data.files.register(data.sourcePath, parser.currentAttributeValue) || { target: undefined, anchor: undefined };
|
|
246
|
-
return {
|
|
247
|
-
pos: parser.currentAttributeValueStart,
|
|
248
|
-
end: parser.currentAttributeValueEnd,
|
|
249
|
-
target,
|
|
250
|
-
targetAnchor: anchor,
|
|
251
|
-
};
|
|
252
|
-
}
|
|
253
|
-
return;
|
|
263
|
+
links.push(...attributes[parser.currentAttributeName](data, parser.currentAttributeValue, parser.currentAttributeValueStart, parser.currentAttributeValueEnd));
|
|
254
264
|
}
|
|
255
265
|
parser.step();
|
|
256
266
|
}
|
|
267
|
+
return links;
|
|
268
|
+
}
|
|
269
|
+
function checkAttributeDirectPath(data, text, pos, end) {
|
|
270
|
+
if (isRelativePath(text.trim())) {
|
|
271
|
+
const { target, anchor } = data.files.register(data.sourcePath, text.trim()) || { target: undefined, anchor: undefined };
|
|
272
|
+
return [{
|
|
273
|
+
pos,
|
|
274
|
+
end,
|
|
275
|
+
target,
|
|
276
|
+
targetAnchor: anchor,
|
|
277
|
+
}];
|
|
278
|
+
}
|
|
279
|
+
return [];
|
|
280
|
+
}
|
|
281
|
+
// See https://html.spec.whatwg.org/multipage/images.html#srcset-attribute
|
|
282
|
+
function checkAttributeSrcSet(data, text, pos, _end) {
|
|
283
|
+
const result = [];
|
|
284
|
+
let textPos = 0;
|
|
285
|
+
parseImageCandidate();
|
|
286
|
+
while (textPos < text.length && text[textPos] == ",") {
|
|
287
|
+
++textPos;
|
|
288
|
+
parseImageCandidate();
|
|
289
|
+
}
|
|
290
|
+
return result;
|
|
291
|
+
function parseImageCandidate() {
|
|
292
|
+
// 1. Zero or more ASCII whitespace
|
|
293
|
+
while (textPos < text.length && /[\t\r\f\n ]/.test(text[textPos]))
|
|
294
|
+
++textPos;
|
|
295
|
+
// 2. A valid non-empty URL that does not start or end with a comma
|
|
296
|
+
// TypeDoc: We don't exactly match this, PR welcome! For now, just permit anything
|
|
297
|
+
// that's not whitespace or a comma
|
|
298
|
+
const url = text.slice(textPos).match(/^[^\t\r\f\n ,]+/);
|
|
299
|
+
if (url && isRelativePath(url[0])) {
|
|
300
|
+
const { target, anchor } = data.files.register(data.sourcePath, url[0]) || { target: undefined, anchor: undefined };
|
|
301
|
+
result.push({
|
|
302
|
+
pos: pos + textPos,
|
|
303
|
+
end: pos + textPos + url[0].length,
|
|
304
|
+
target,
|
|
305
|
+
targetAnchor: anchor,
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
textPos += url ? url[0].length : 0;
|
|
309
|
+
// 3. Zero or more ASCII whitespace
|
|
310
|
+
while (textPos < text.length && /[\t\r\f\n ]/.test(text[textPos]))
|
|
311
|
+
++textPos;
|
|
312
|
+
// 4. Zero or one of the following:
|
|
313
|
+
{
|
|
314
|
+
// A width descriptor, consisting of: ASCII whitespace, a valid non-negative integer giving
|
|
315
|
+
// a number greater than zero representing the width descriptor value, and a U+0077 LATIN
|
|
316
|
+
// SMALL LETTER W character.
|
|
317
|
+
const w = text.slice(textPos).match(/^\+?\d+\s*w/);
|
|
318
|
+
textPos += w ? w[0].length : 0;
|
|
319
|
+
// A pixel density descriptor, consisting of: ASCII whitespace, a valid floating-point number
|
|
320
|
+
// giving a number greater than zero representing the pixel density descriptor value, and a
|
|
321
|
+
// U+0078 LATIN SMALL LETTER X character.
|
|
322
|
+
if (!w) {
|
|
323
|
+
const x = text.slice(textPos).match(/^\+?\d+(\.\d+)?([eE][+-]\d+)?\s*x/);
|
|
324
|
+
textPos += x ? x[0].length : 0;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
// 5. Zero or more ASCII whitespace
|
|
328
|
+
while (textPos < text.length && /[\t\r\f\n ]/.test(text[textPos]))
|
|
329
|
+
++textPos;
|
|
330
|
+
}
|
|
257
331
|
}
|
|
258
332
|
function isRelativePath(link) {
|
|
259
333
|
// Lots of edge cases encoded right here!
|
|
@@ -67,6 +67,15 @@ export declare class Context {
|
|
|
67
67
|
* This is available on Context so that it can be monkey-patched by typedoc-plugin-missing-exports
|
|
68
68
|
*/
|
|
69
69
|
createSymbolReference(symbol: ts.Symbol, context: Context, name?: string): ReferenceType;
|
|
70
|
+
/**
|
|
71
|
+
* Create a stable {@link ReflectionSymbolId} for the provided symbol,
|
|
72
|
+
* optionally targeting a specific declaration.
|
|
73
|
+
*
|
|
74
|
+
* @privateRemarks
|
|
75
|
+
* This is available on Context so that it can be monkey-patched by typedoc-plugin-missing-exports
|
|
76
|
+
* It might also turn out to be generally useful for other plugin users.
|
|
77
|
+
*/
|
|
78
|
+
createSymbolId(symbol: ts.Symbol, declaration?: ts.Declaration): import("../models/ReflectionSymbolId.js").ReflectionSymbolId;
|
|
70
79
|
addChild(reflection: DeclarationReflection | DocumentReflection): void;
|
|
71
80
|
shouldIgnore(symbol: ts.Symbol): boolean;
|
|
72
81
|
/**
|
|
@@ -81,6 +90,7 @@ export declare class Context {
|
|
|
81
90
|
getSymbolFromReflection(reflection: Reflection): ts.Symbol | undefined;
|
|
82
91
|
/** @internal */
|
|
83
92
|
setActiveProgram(program: ts.Program | undefined): void;
|
|
93
|
+
private createCommentContext;
|
|
84
94
|
getComment(symbol: ts.Symbol, kind: ReflectionKind): Comment | undefined;
|
|
85
95
|
getNodeComment(node: ts.Node, moduleComment: boolean): Comment | undefined;
|
|
86
96
|
getFileComment(node: ts.SourceFile): Comment | undefined;
|