typedoc 0.28.7 → 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/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/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/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/GroupPlugin.d.ts +1 -1
- package/dist/lib/converter/plugins/ImplementsPlugin.js +49 -11
- package/dist/lib/converter/types.js +2 -3
- package/dist/lib/internationalization/locales/en.cjs +1 -0
- package/dist/lib/internationalization/locales/en.d.cts +1 -0
- 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 +38 -9
- package/dist/lib/utils/options/readers/arguments.js +2 -0
- package/dist/lib/utils/options/sources/typedoc.js +1 -1
- package/dist/lib/utils/plugins.d.ts +2 -1
- package/dist/lib/utils/plugins.js +26 -17
- package/dist/lib/utils-common/path.d.ts +6 -0
- package/dist/lib/utils-common/validation.js +1 -1
- package/package.json +1 -1
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
|
}
|
|
@@ -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,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;
|
|
@@ -4,10 +4,10 @@ import { Comment, ContainerReflection, DeclarationReflection, ReferenceType, Ref
|
|
|
4
4
|
import { isNamedNode } from "./utils/nodes.js";
|
|
5
5
|
import { ConverterEvents } from "./converter-events.js";
|
|
6
6
|
import { resolveAliasedSymbol } from "./utils/symbols.js";
|
|
7
|
-
import { getComment, getFileComment, getJsDocComment, getNodeComment, getSignatureComment } from "./comments/index.js";
|
|
7
|
+
import { getComment, getFileComment, getJsDocComment, getNodeComment, getSignatureComment, } from "./comments/index.js";
|
|
8
8
|
import { getHumanName, getQualifiedName } from "../utils/tsutils.js";
|
|
9
9
|
import { findPackageForPath, normalizePath } from "#node-utils";
|
|
10
|
-
import {
|
|
10
|
+
import { createSymbolIdImpl } from "./factories/symbol-id.js";
|
|
11
11
|
import { removeIf } from "#utils";
|
|
12
12
|
/**
|
|
13
13
|
* The context describes the current state the converter is in.
|
|
@@ -185,7 +185,7 @@ export class Context {
|
|
|
185
185
|
* This is available on Context so that it can be monkey-patched by typedoc-plugin-missing-exports
|
|
186
186
|
*/
|
|
187
187
|
createSymbolReference(symbol, context, name) {
|
|
188
|
-
const ref = ReferenceType.createUnresolvedReference(name ?? symbol.name, createSymbolId(symbol), context.project, getQualifiedName(symbol, name ?? symbol.name));
|
|
188
|
+
const ref = ReferenceType.createUnresolvedReference(name ?? symbol.name, this.createSymbolId(symbol), context.project, getQualifiedName(symbol, name ?? symbol.name));
|
|
189
189
|
ref.refersToTypeParameter = !!(symbol.flags & ts.SymbolFlags.TypeParameter);
|
|
190
190
|
const symbolPath = symbol.declarations?.[0]?.getSourceFile().fileName;
|
|
191
191
|
if (!symbolPath)
|
|
@@ -193,6 +193,17 @@ export class Context {
|
|
|
193
193
|
ref.package = findPackageForPath(symbolPath)?.[0];
|
|
194
194
|
return ref;
|
|
195
195
|
}
|
|
196
|
+
/**
|
|
197
|
+
* Create a stable {@link ReflectionSymbolId} for the provided symbol,
|
|
198
|
+
* optionally targeting a specific declaration.
|
|
199
|
+
*
|
|
200
|
+
* @privateRemarks
|
|
201
|
+
* This is available on Context so that it can be monkey-patched by typedoc-plugin-missing-exports
|
|
202
|
+
* It might also turn out to be generally useful for other plugin users.
|
|
203
|
+
*/
|
|
204
|
+
createSymbolId(symbol, declaration) {
|
|
205
|
+
return createSymbolIdImpl(symbol, declaration);
|
|
206
|
+
}
|
|
196
207
|
addChild(reflection) {
|
|
197
208
|
if (this.scope instanceof ContainerReflection) {
|
|
198
209
|
this.scope.addChild(reflection);
|
|
@@ -211,7 +222,7 @@ export class Context {
|
|
|
211
222
|
registerReflection(reflection, symbol, filePath) {
|
|
212
223
|
if (symbol) {
|
|
213
224
|
this.reflectionIdToSymbolMap.set(reflection.id, symbol);
|
|
214
|
-
const id = createSymbolId(symbol);
|
|
225
|
+
const id = this.createSymbolId(symbol);
|
|
215
226
|
// #2466
|
|
216
227
|
// If we just registered a member of a class or interface, then we need to check if
|
|
217
228
|
// we've registered this symbol before under the wrong parent reflection.
|
|
@@ -237,7 +248,7 @@ export class Context {
|
|
|
237
248
|
}
|
|
238
249
|
}
|
|
239
250
|
getReflectionFromSymbol(symbol) {
|
|
240
|
-
return this.project.getReflectionFromSymbolId(createSymbolId(symbol));
|
|
251
|
+
return this.project.getReflectionFromSymbolId(this.createSymbolId(symbol));
|
|
241
252
|
}
|
|
242
253
|
getSymbolFromReflection(reflection) {
|
|
243
254
|
return this.reflectionIdToSymbolMap.get(reflection.id);
|
|
@@ -246,20 +257,29 @@ export class Context {
|
|
|
246
257
|
setActiveProgram(program) {
|
|
247
258
|
this._program = program;
|
|
248
259
|
}
|
|
260
|
+
createCommentContext() {
|
|
261
|
+
return {
|
|
262
|
+
config: this.converter.config,
|
|
263
|
+
logger: this.logger,
|
|
264
|
+
checker: this.checker,
|
|
265
|
+
files: this.project.files,
|
|
266
|
+
createSymbolId: (s, d) => this.createSymbolId(s, d),
|
|
267
|
+
};
|
|
268
|
+
}
|
|
249
269
|
getComment(symbol, kind) {
|
|
250
|
-
return getComment(symbol, kind, this.
|
|
270
|
+
return getComment(symbol, kind, this.createCommentContext());
|
|
251
271
|
}
|
|
252
272
|
getNodeComment(node, moduleComment) {
|
|
253
|
-
return getNodeComment(node, moduleComment, this.
|
|
273
|
+
return getNodeComment(node, moduleComment, this.createCommentContext());
|
|
254
274
|
}
|
|
255
275
|
getFileComment(node) {
|
|
256
|
-
return getFileComment(node, this.
|
|
276
|
+
return getFileComment(node, this.createCommentContext());
|
|
257
277
|
}
|
|
258
278
|
getJsDocComment(declaration) {
|
|
259
|
-
return getJsDocComment(declaration, this.
|
|
279
|
+
return getJsDocComment(declaration, this.createCommentContext());
|
|
260
280
|
}
|
|
261
281
|
getSignatureComment(declaration) {
|
|
262
|
-
return getSignatureComment(declaration, this.
|
|
282
|
+
return getSignatureComment(declaration, this.createCommentContext());
|
|
263
283
|
}
|
|
264
284
|
shouldInline(symbol, name) {
|
|
265
285
|
if (this.preventInline.has(name))
|
|
@@ -4,7 +4,6 @@ import { DeclarationReflection, IntrinsicType, ParameterReflection, PredicateTyp
|
|
|
4
4
|
import { ConverterEvents } from "../converter-events.js";
|
|
5
5
|
import { convertDefaultValue } from "../convert-expression.js";
|
|
6
6
|
import { removeUndefined } from "../utils/reflections.js";
|
|
7
|
-
import { createSymbolId } from "./symbol-id.js";
|
|
8
7
|
export function createSignature(context, kind, signature, symbol, declaration) {
|
|
9
8
|
assert(context.scope instanceof DeclarationReflection);
|
|
10
9
|
declaration ||= signature.getDeclaration();
|
|
@@ -17,7 +16,7 @@ export function createSignature(context, kind, signature, symbol, declaration) {
|
|
|
17
16
|
sigRef.setFlag(ReflectionFlag.Static);
|
|
18
17
|
}
|
|
19
18
|
if (symbol && declaration) {
|
|
20
|
-
context.project.registerSymbolId(sigRef, createSymbolId(symbol, declaration));
|
|
19
|
+
context.project.registerSymbolId(sigRef, context.createSymbolId(symbol, declaration));
|
|
21
20
|
}
|
|
22
21
|
let parentReflection = context.scope;
|
|
23
22
|
if (parentReflection.kindOf(ReflectionKind.TypeLiteral) &&
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { ReflectionSymbolId } from "#models";
|
|
2
2
|
import ts from "typescript";
|
|
3
|
-
export declare function
|
|
3
|
+
export declare function createSymbolIdImpl(symbol: ts.Symbol, declaration?: ts.Declaration): ReflectionSymbolId;
|
|
4
4
|
export declare function addInferredDeclarationMapPaths(opts: ts.CompilerOptions, files: readonly string[]): void;
|
|
@@ -7,7 +7,8 @@ import ts from "typescript";
|
|
|
7
7
|
const declarationMapCache = new Map();
|
|
8
8
|
let transientCount = 0;
|
|
9
9
|
const transientIds = new WeakMap();
|
|
10
|
-
|
|
10
|
+
// Don't use this directly, use Context.createSymbolId instead.
|
|
11
|
+
export function createSymbolIdImpl(symbol, declaration) {
|
|
11
12
|
declaration ??= symbol.declarations?.[0];
|
|
12
13
|
const tsSource = declaration?.getSourceFile().fileName ?? "";
|
|
13
14
|
const sourceFileName = resolveDeclarationMaps(tsSource);
|
|
@@ -6,7 +6,6 @@ import ts from "typescript";
|
|
|
6
6
|
import { DeclarationReflection, IntrinsicType, ReflectionKind, ReflectionType, SignatureReflection, } from "../models/index.js";
|
|
7
7
|
import { ConverterEvents } from "./converter-events.js";
|
|
8
8
|
import { convertParameterNodes, convertTemplateParameterNodes } from "./factories/signature.js";
|
|
9
|
-
import { createSymbolId } from "./factories/symbol-id.js";
|
|
10
9
|
export function convertJsDocAlias(context, symbol, declaration, exportSymbol) {
|
|
11
10
|
if (declaration.typeExpression &&
|
|
12
11
|
ts.isJSDocTypeLiteral(declaration.typeExpression)) {
|
|
@@ -57,7 +56,7 @@ function convertJsDocSignature(context, node) {
|
|
|
57
56
|
context.registerReflection(reflection, symbol);
|
|
58
57
|
context.converter.trigger(ConverterEvents.CREATE_DECLARATION, context, reflection);
|
|
59
58
|
const signature = new SignatureReflection("__type", ReflectionKind.CallSignature, reflection);
|
|
60
|
-
context.project.registerSymbolId(signature, createSymbolId(symbol, node));
|
|
59
|
+
context.project.registerSymbolId(signature, context.createSymbolId(symbol, node));
|
|
61
60
|
context.registerReflection(signature, void 0);
|
|
62
61
|
const signatureCtx = rc.withScope(signature);
|
|
63
62
|
reflection.signatures = [signature];
|
|
@@ -40,7 +40,7 @@ export declare class GroupPlugin extends ConverterComponent {
|
|
|
40
40
|
* @returns An array containing all children of the given reflection grouped by their kind.
|
|
41
41
|
*/
|
|
42
42
|
getReflectionGroups(parent: ContainerReflection, reflections: Array<DeclarationReflection | DocumentReflection>): ReflectionGroup[];
|
|
43
|
-
getSortFunction(reflection: ContainerReflection): (reflections:
|
|
43
|
+
getSortFunction(reflection: ContainerReflection): (reflections: Array<DeclarationReflection | DocumentReflection>) => void;
|
|
44
44
|
/**
|
|
45
45
|
* Callback used to sort groups by name.
|
|
46
46
|
*/
|
|
@@ -58,7 +58,9 @@ export class ImplementsPlugin extends ConverterComponent {
|
|
|
58
58
|
});
|
|
59
59
|
}
|
|
60
60
|
analyzeInheritance(project, reflection) {
|
|
61
|
-
|
|
61
|
+
if (!reflection.extendedTypes)
|
|
62
|
+
return;
|
|
63
|
+
const extendedTypes = filterMap(reflection.extendedTypes, (type) => {
|
|
62
64
|
return type instanceof ReferenceType &&
|
|
63
65
|
type.reflection instanceof DeclarationReflection
|
|
64
66
|
? type
|
|
@@ -73,13 +75,42 @@ export class ImplementsPlugin extends ConverterComponent {
|
|
|
73
75
|
? "overwrites"
|
|
74
76
|
: "inheritedFrom";
|
|
75
77
|
for (const [childSig, parentSig] of zip(child.signatures ?? [], parentMember.signatures ?? [])) {
|
|
76
|
-
|
|
78
|
+
// If we're already pointing at something because TS said we should reference
|
|
79
|
+
// it, then don't overwrite the reference.
|
|
80
|
+
if (!childSig[key]?.reflection) {
|
|
81
|
+
childSig[key] = ReferenceType.createResolvedReference(`${parent.name}.${parentMember.name}`, parentSig, project);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
if (!child[key]?.reflection) {
|
|
85
|
+
child[key] = ReferenceType.createResolvedReference(`${parent.name}.${parentMember.name}`, parentMember, project);
|
|
77
86
|
}
|
|
78
|
-
child[key] = ReferenceType.createResolvedReference(`${parent.name}.${parentMember.name}`, parentMember, project);
|
|
79
87
|
this.handleInheritedComments(child, parentMember);
|
|
80
88
|
}
|
|
81
89
|
}
|
|
82
90
|
}
|
|
91
|
+
// #2978, this is very unfortunate. If a child's parent links are broken at this point,
|
|
92
|
+
// we replace them with an intentionally broken link so that they won't ever be resolved.
|
|
93
|
+
// This is done because if we don't do it then we run into issues where we have a link which
|
|
94
|
+
// points to some ReflectionSymbolId which might not exist now, but once we've gone through
|
|
95
|
+
// serialization/deserialization, might point to an unexpected location. (See the mixin
|
|
96
|
+
// converter tests, I suspect this might actually be an indication of something else slightly
|
|
97
|
+
// broken there, but don't want to spend more time with this right now.)
|
|
98
|
+
for (const child of reflection.children || []) {
|
|
99
|
+
if (child.inheritedFrom && !child.inheritedFrom.reflection) {
|
|
100
|
+
child.inheritedFrom = ReferenceType.createBrokenReference(child.inheritedFrom.name, project);
|
|
101
|
+
}
|
|
102
|
+
if (child.overwrites && !child.overwrites.reflection) {
|
|
103
|
+
child.overwrites = ReferenceType.createBrokenReference(child.overwrites.name, project);
|
|
104
|
+
}
|
|
105
|
+
for (const childSig of child.getAllSignatures()) {
|
|
106
|
+
if (childSig.inheritedFrom && !childSig.inheritedFrom.reflection) {
|
|
107
|
+
childSig.inheritedFrom = ReferenceType.createBrokenReference(childSig.inheritedFrom.name, project);
|
|
108
|
+
}
|
|
109
|
+
if (childSig.overwrites && !childSig.overwrites.reflection) {
|
|
110
|
+
childSig.overwrites = ReferenceType.createBrokenReference(childSig.overwrites.name, project);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
83
114
|
}
|
|
84
115
|
onResolveEnd(context) {
|
|
85
116
|
this.resolve(context.project);
|
|
@@ -310,8 +341,19 @@ function findProperty(reflection, parent) {
|
|
|
310
341
|
});
|
|
311
342
|
}
|
|
312
343
|
function createLink(context, reflection, clause, expr, symbol, isInherit) {
|
|
313
|
-
const project = context.project;
|
|
314
344
|
const name = `${expr.expression.getText()}.${getHumanName(symbol.name)}`;
|
|
345
|
+
// We should always have rootSymbols, but check just in case. We use the first
|
|
346
|
+
// symbol here as TypeDoc's models don't have multiple symbols for the parent
|
|
347
|
+
// reference. This is technically wrong because symbols might be declared in
|
|
348
|
+
// multiple locations (interface declaration merging), but that's an uncommon
|
|
349
|
+
// enough use case that it doesn't seem worthwhile to complicate the rest of the
|
|
350
|
+
// world to deal with it.
|
|
351
|
+
// Note that we also need to check that the root symbol isn't this symbol.
|
|
352
|
+
// This seems to happen sometimes when dealing with interface inheritance.
|
|
353
|
+
const rootSymbols = context.checker.getRootSymbols(symbol);
|
|
354
|
+
const ref = rootSymbols.length && rootSymbols[0] != symbol
|
|
355
|
+
? context.createSymbolReference(rootSymbols[0], context, name)
|
|
356
|
+
: ReferenceType.createBrokenReference(name, context.project);
|
|
315
357
|
link(reflection);
|
|
316
358
|
link(reflection.getSignature);
|
|
317
359
|
link(reflection.setSignature);
|
|
@@ -321,23 +363,19 @@ function createLink(context, reflection, clause, expr, symbol, isInherit) {
|
|
|
321
363
|
for (const sig of reflection.signatures ?? []) {
|
|
322
364
|
link(sig);
|
|
323
365
|
}
|
|
324
|
-
// Intentionally create broken links here. These will be replaced with real links during
|
|
325
|
-
// resolution if we can do so. We create broken links rather than real links because in the
|
|
326
|
-
// case of an inherited symbol, we'll end up referencing a single symbol ID rather than one
|
|
327
|
-
// for each class.
|
|
328
366
|
function link(target) {
|
|
329
367
|
if (!target)
|
|
330
368
|
return;
|
|
331
369
|
if (clause.token === ts.SyntaxKind.ImplementsKeyword) {
|
|
332
|
-
target.implementationOf ??=
|
|
370
|
+
target.implementationOf ??= ref;
|
|
333
371
|
return;
|
|
334
372
|
}
|
|
335
373
|
if (isInherit) {
|
|
336
374
|
target.setFlag(ReflectionFlag.Inherited);
|
|
337
|
-
target.inheritedFrom ??=
|
|
375
|
+
target.inheritedFrom ??= ref;
|
|
338
376
|
}
|
|
339
377
|
else {
|
|
340
|
-
target.overwrites ??=
|
|
378
|
+
target.overwrites ??= ref;
|
|
341
379
|
}
|
|
342
380
|
}
|
|
343
381
|
}
|
|
@@ -8,7 +8,6 @@ import { convertParameterNodes, convertTypeParameterNodes, createSignature } fro
|
|
|
8
8
|
import { convertSymbol } from "./symbols.js";
|
|
9
9
|
import { isObjectType, isTypeReference } from "./utils/nodes.js";
|
|
10
10
|
import { removeUndefined } from "./utils/reflections.js";
|
|
11
|
-
import { createSymbolId } from "./factories/symbol-id.js";
|
|
12
11
|
const converters = new Map();
|
|
13
12
|
export function loadConverters() {
|
|
14
13
|
if (converters.size)
|
|
@@ -159,7 +158,7 @@ const constructorConverter = {
|
|
|
159
158
|
if (node.modifiers?.some((m) => m.kind === ts.SyntaxKind.AbstractKeyword)) {
|
|
160
159
|
signature.setFlag(ReflectionFlag.Abstract);
|
|
161
160
|
}
|
|
162
|
-
context.project.registerSymbolId(signature, createSymbolId(symbol, node));
|
|
161
|
+
context.project.registerSymbolId(signature, context.createSymbolId(symbol, node));
|
|
163
162
|
context.registerReflection(signature, void 0);
|
|
164
163
|
const signatureCtx = rc.withScope(signature);
|
|
165
164
|
reflection.signatures = [signature];
|
|
@@ -208,7 +207,7 @@ const functionTypeConverter = {
|
|
|
208
207
|
context.registerReflection(reflection, symbol);
|
|
209
208
|
context.converter.trigger(ConverterEvents.CREATE_DECLARATION, context, reflection);
|
|
210
209
|
const signature = new SignatureReflection("__type", ReflectionKind.CallSignature, reflection);
|
|
211
|
-
context.project.registerSymbolId(signature, createSymbolId(symbol, node));
|
|
210
|
+
context.project.registerSymbolId(signature, context.createSymbolId(symbol, node));
|
|
212
211
|
context.registerReflection(signature, undefined);
|
|
213
212
|
const signatureCtx = rc.withScope(signature);
|
|
214
213
|
reflection.signatures = [signature];
|
|
@@ -276,6 +276,7 @@ module.exports = {
|
|
|
276
276
|
favicon_must_have_one_of_the_following_extensions_0: "Favicon must have one of the following extensions: {0}",
|
|
277
277
|
option_0_must_be_an_object: "The '{0}' option must be a non-array object",
|
|
278
278
|
option_0_must_be_an_array_of_string: "The '{0}' option must be set to an array of strings",
|
|
279
|
+
option_0_must_be_an_array_of_string_or_functions: "The '{0}' option must be set to an array of strings/functions",
|
|
279
280
|
option_0_must_be_a_function: "The '{0}' option must be a function",
|
|
280
281
|
option_0_must_be_object_with_urls: `{0} must be an object with string labels as keys and URL values`,
|
|
281
282
|
visibility_filters_only_include_0: `visibilityFilters can only include the following non-@ keys: {0}`,
|
|
@@ -260,6 +260,7 @@ declare const _default: {
|
|
|
260
260
|
readonly favicon_must_have_one_of_the_following_extensions_0: "Favicon must have one of the following extensions: {0}";
|
|
261
261
|
readonly option_0_must_be_an_object: "The '{0}' option must be a non-array object";
|
|
262
262
|
readonly option_0_must_be_an_array_of_string: "The '{0}' option must be set to an array of strings";
|
|
263
|
+
readonly option_0_must_be_an_array_of_string_or_functions: "The '{0}' option must be set to an array of strings/functions";
|
|
263
264
|
readonly option_0_must_be_a_function: "The '{0}' option must be a function";
|
|
264
265
|
readonly option_0_must_be_object_with_urls: "{0} must be an object with string labels as keys and URL values";
|
|
265
266
|
readonly visibility_filters_only_include_0: "visibilityFilters can only include the following non-@ keys: {0}";
|
|
@@ -37,7 +37,7 @@ export declare const SCHEMA_VERSION = "2.0";
|
|
|
37
37
|
export type ModelToObject<T> = [T] extends [Array<infer U>] ? ModelToObject<U>[] : [
|
|
38
38
|
M.SomeType
|
|
39
39
|
] extends [T] ? SomeType : _ModelToObject<T>;
|
|
40
|
-
type _ModelToObject<T> = T extends Primitive ? T : Required<T> extends Required<M.ReflectionGroup> ? ReflectionGroup : Required<T> extends Required<M.ReflectionCategory> ? ReflectionCategory : T extends M.ReflectionVariant[keyof M.ReflectionVariant] ? ReflectionVariantMap[T["variant"]] : T extends M.SomeType ? TypeKindMap[T["type"]] : T extends M.Type ? SomeType : T extends M.Comment ? Comment : T extends M.CommentTag ? CommentTag : T extends M.CommentDisplayPart ? CommentDisplayPart : T extends M.SourceReference ? SourceReference : T extends M.FileRegistry ? FileRegistry : never;
|
|
40
|
+
type _ModelToObject<T> = T extends Primitive ? T : Required<T> extends Required<M.ReflectionGroup> ? ReflectionGroup : Required<T> extends Required<M.ReflectionCategory> ? ReflectionCategory : T extends M.ReflectionVariant[keyof M.ReflectionVariant] ? ReflectionVariantMap[T["variant"]] : T extends M.SomeType ? TypeKindMap[T["type"]] : T extends M.Type ? SomeType : T extends M.Comment ? Comment : T extends M.CommentTag ? CommentTag : T extends M.CommentDisplayPart ? CommentDisplayPart : T extends M.SourceReference ? SourceReference : T extends M.FileRegistry ? FileRegistry : T extends M.ReflectionSymbolId ? ReflectionSymbolId : never;
|
|
41
41
|
type Primitive = string | number | undefined | null | boolean;
|
|
42
42
|
type ToSerialized<T> = T extends Primitive ? T : T extends bigint ? {
|
|
43
43
|
value: string;
|
|
@@ -2,8 +2,9 @@ import type { BundledTheme as ShikiTheme } from "@gerrit0/mini-shiki";
|
|
|
2
2
|
import type { SortStrategy } from "../sort.js";
|
|
3
3
|
import type { EntryPointStrategy } from "../entry-point.js";
|
|
4
4
|
import type { ReflectionKind } from "../../models/kind.js";
|
|
5
|
-
import { type GlobString, type LogLevel, type NeverIfInternal, type NormalizedPath, type NormalizedPathOrModule } from "#utils";
|
|
5
|
+
import { type GlobString, type LogLevel, type NeverIfInternal, type NormalizedPath, type NormalizedPathOrModule, type NormalizedPathOrModuleOrFunction } from "#utils";
|
|
6
6
|
import type { TranslationProxy } from "../../internationalization/internationalization.js";
|
|
7
|
+
import type { Application } from "../../application.js";
|
|
7
8
|
/** @enum */
|
|
8
9
|
export declare const EmitStrategy: {
|
|
9
10
|
readonly both: "both";
|
|
@@ -40,7 +41,7 @@ export declare const rootPackageOptions: readonly ["plugin", "packageOptions", "
|
|
|
40
41
|
* @interface
|
|
41
42
|
*/
|
|
42
43
|
export type TypeDocOptions = {
|
|
43
|
-
[K in keyof TypeDocOptionMap]?: unknown extends TypeDocOptionMap[K] ? unknown : TypeDocOptionMap[K] extends ManuallyValidatedOption<infer ManuallyValidated> ? ManuallyValidated : TypeDocOptionMap[K] extends NormalizedPath[] | NormalizedPathOrModule[] | GlobString[] ? string[] : TypeDocOptionMap[K] extends NormalizedPath ? string : TypeDocOptionMap[K] extends string | string[] | number | boolean ? TypeDocOptionMap[K] : TypeDocOptionMap[K] extends Record<string, boolean> ? Partial<TypeDocOptionMap[K]> | boolean : keyof TypeDocOptionMap[K] | TypeDocOptionMap[K][keyof TypeDocOptionMap[K]];
|
|
44
|
+
[K in keyof TypeDocOptionMap]?: unknown extends TypeDocOptionMap[K] ? unknown : TypeDocOptionMap[K] extends ManuallyValidatedOption<infer ManuallyValidated> ? ManuallyValidated : TypeDocOptionMap[K] extends NormalizedPath[] | NormalizedPathOrModule[] | NormalizedPathOrModuleOrFunction[] | GlobString[] ? string[] : TypeDocOptionMap[K] extends NormalizedPath ? string : TypeDocOptionMap[K] extends string | string[] | number | boolean ? TypeDocOptionMap[K] : TypeDocOptionMap[K] extends Record<string, boolean> ? Partial<TypeDocOptionMap[K]> | boolean : keyof TypeDocOptionMap[K] | TypeDocOptionMap[K][keyof TypeDocOptionMap[K]];
|
|
44
45
|
};
|
|
45
46
|
/**
|
|
46
47
|
* Describes all TypeDoc specific options as returned by {@link Options.getValue}, this is
|
|
@@ -50,7 +51,7 @@ export type TypeDocOptions = {
|
|
|
50
51
|
* @interface
|
|
51
52
|
*/
|
|
52
53
|
export type TypeDocOptionValues = {
|
|
53
|
-
[K in keyof TypeDocOptionMap]: unknown extends TypeDocOptionMap[K] ? unknown : TypeDocOptionMap[K] extends ManuallyValidatedOption<infer ManuallyValidated> ? ManuallyValidated : TypeDocOptionMap[K] extends string | string[] | GlobString[] | number | boolean | Record<string, boolean> ? TypeDocOptionMap[K] : TypeDocOptionMap[K][keyof TypeDocOptionMap[K]];
|
|
54
|
+
[K in keyof TypeDocOptionMap]: unknown extends TypeDocOptionMap[K] ? unknown : TypeDocOptionMap[K] extends ManuallyValidatedOption<infer ManuallyValidated> ? ManuallyValidated : TypeDocOptionMap[K] extends string | string[] | GlobString[] | NormalizedPathOrModule[] | NormalizedPathOrModuleOrFunction[] | number | boolean | Record<string, boolean> ? TypeDocOptionMap[K] : TypeDocOptionMap[K][keyof TypeDocOptionMap[K]];
|
|
54
55
|
};
|
|
55
56
|
/**
|
|
56
57
|
* Describes TypeDoc options suitable for setting within the `packageOptions` setting.
|
|
@@ -78,7 +79,7 @@ export interface TypeDocOptionMap {
|
|
|
78
79
|
options: NormalizedPath;
|
|
79
80
|
tsconfig: NormalizedPath;
|
|
80
81
|
compilerOptions: unknown;
|
|
81
|
-
plugin:
|
|
82
|
+
plugin: NormalizedPathOrModuleOrFunction[];
|
|
82
83
|
lang: string;
|
|
83
84
|
locales: ManuallyValidatedOption<Record<string, Record<string, string>>>;
|
|
84
85
|
packageOptions: ManuallyValidatedOption<TypeDocPackageOptions>;
|
|
@@ -276,7 +277,7 @@ export type JsDocCompatibility = {
|
|
|
276
277
|
/**
|
|
277
278
|
* Converts a given TypeDoc option key to the type of the declaration expected.
|
|
278
279
|
*/
|
|
279
|
-
export type KeyToDeclaration<K extends keyof TypeDocOptionMap> = TypeDocOptionMap[K] extends boolean ? BooleanDeclarationOption : TypeDocOptionMap[K] extends string | NormalizedPath ? StringDeclarationOption : TypeDocOptionMap[K] extends number ? NumberDeclarationOption : TypeDocOptionMap[K] extends GlobString[] ? GlobArrayDeclarationOption : TypeDocOptionMap[K] extends string[] | NormalizedPath[] | NormalizedPathOrModule[] ? ArrayDeclarationOption : unknown extends TypeDocOptionMap[K] ? MixedDeclarationOption | ObjectDeclarationOption : TypeDocOptionMap[K] extends ManuallyValidatedOption<unknown> ? (MixedDeclarationOption & {
|
|
280
|
+
export type KeyToDeclaration<K extends keyof TypeDocOptionMap> = TypeDocOptionMap[K] extends boolean ? BooleanDeclarationOption : TypeDocOptionMap[K] extends string | NormalizedPath ? StringDeclarationOption : TypeDocOptionMap[K] extends number ? NumberDeclarationOption : TypeDocOptionMap[K] extends GlobString[] ? GlobArrayDeclarationOption : TypeDocOptionMap[K] extends string[] | NormalizedPath[] | NormalizedPathOrModule[] | NormalizedPathOrModuleOrFunction[] ? ArrayDeclarationOption : unknown extends TypeDocOptionMap[K] ? MixedDeclarationOption | ObjectDeclarationOption : TypeDocOptionMap[K] extends ManuallyValidatedOption<unknown> ? (MixedDeclarationOption & {
|
|
280
281
|
validate(value: unknown, i18n: TranslationProxy): void;
|
|
281
282
|
}) | (ObjectDeclarationOption & {
|
|
282
283
|
validate(value: unknown, i18n: TranslationProxy): void;
|
|
@@ -306,20 +307,26 @@ export declare enum ParameterType {
|
|
|
306
307
|
PathArray = 8,
|
|
307
308
|
/**
|
|
308
309
|
* Resolved according to the config directory if it starts with `.`
|
|
310
|
+
* @deprecated since 0.28.8, will be removed in 0.29
|
|
309
311
|
*/
|
|
310
312
|
ModuleArray = 9,
|
|
313
|
+
/**
|
|
314
|
+
* Resolved according to the config directory if it starts with `.`
|
|
315
|
+
* @internal - only intended for use with the plugin option
|
|
316
|
+
*/
|
|
317
|
+
PluginArray = 10,
|
|
311
318
|
/**
|
|
312
319
|
* Relative to the config directory.
|
|
313
320
|
*/
|
|
314
|
-
GlobArray =
|
|
321
|
+
GlobArray = 11,
|
|
315
322
|
/**
|
|
316
323
|
* An object which partially merges user-set values into the defaults.
|
|
317
324
|
*/
|
|
318
|
-
Object =
|
|
325
|
+
Object = 12,
|
|
319
326
|
/**
|
|
320
327
|
* An object with true/false flags
|
|
321
328
|
*/
|
|
322
|
-
Flags =
|
|
329
|
+
Flags = 13
|
|
323
330
|
}
|
|
324
331
|
export interface DeclarationOptionBase {
|
|
325
332
|
/**
|
|
@@ -401,7 +408,7 @@ export interface BooleanDeclarationOption extends DeclarationOptionBase {
|
|
|
401
408
|
defaultValue?: boolean;
|
|
402
409
|
}
|
|
403
410
|
export interface ArrayDeclarationOption extends DeclarationOptionBase {
|
|
404
|
-
type: ParameterType.Array | ParameterType.PathArray | ParameterType.ModuleArray;
|
|
411
|
+
type: ParameterType.Array | ParameterType.PathArray | ParameterType.ModuleArray | ParameterType.PluginArray;
|
|
405
412
|
/**
|
|
406
413
|
* If not specified defaults to an empty array.
|
|
407
414
|
*/
|
|
@@ -482,6 +489,7 @@ export interface ParameterTypeToOptionTypeMap {
|
|
|
482
489
|
[ParameterType.Array]: string[];
|
|
483
490
|
[ParameterType.PathArray]: NormalizedPath[];
|
|
484
491
|
[ParameterType.ModuleArray]: NormalizedPathOrModule[];
|
|
492
|
+
[ParameterType.PluginArray]: Array<NormalizedPathOrModule | ((app: Application) => void | Promise<void>)>;
|
|
485
493
|
[ParameterType.GlobArray]: GlobString[];
|
|
486
494
|
[ParameterType.Flags]: Record<string, boolean>;
|
|
487
495
|
[ParameterType.Map]: unknown;
|
|
@@ -112,20 +112,26 @@ export var ParameterType;
|
|
|
112
112
|
ParameterType[ParameterType["PathArray"] = 8] = "PathArray";
|
|
113
113
|
/**
|
|
114
114
|
* Resolved according to the config directory if it starts with `.`
|
|
115
|
+
* @deprecated since 0.28.8, will be removed in 0.29
|
|
115
116
|
*/
|
|
116
117
|
ParameterType[ParameterType["ModuleArray"] = 9] = "ModuleArray";
|
|
118
|
+
/**
|
|
119
|
+
* Resolved according to the config directory if it starts with `.`
|
|
120
|
+
* @internal - only intended for use with the plugin option
|
|
121
|
+
*/
|
|
122
|
+
ParameterType[ParameterType["PluginArray"] = 10] = "PluginArray";
|
|
117
123
|
/**
|
|
118
124
|
* Relative to the config directory.
|
|
119
125
|
*/
|
|
120
|
-
ParameterType[ParameterType["GlobArray"] =
|
|
126
|
+
ParameterType[ParameterType["GlobArray"] = 11] = "GlobArray";
|
|
121
127
|
/**
|
|
122
128
|
* An object which partially merges user-set values into the defaults.
|
|
123
129
|
*/
|
|
124
|
-
ParameterType[ParameterType["Object"] =
|
|
130
|
+
ParameterType[ParameterType["Object"] = 12] = "Object";
|
|
125
131
|
/**
|
|
126
132
|
* An object with true/false flags
|
|
127
133
|
*/
|
|
128
|
-
ParameterType[ParameterType["Flags"] =
|
|
134
|
+
ParameterType[ParameterType["Flags"] = 13] = "Flags";
|
|
129
135
|
})(ParameterType || (ParameterType = {}));
|
|
130
136
|
function toStringArray(value, option) {
|
|
131
137
|
if (Array.isArray(value) && value.every(v => typeof v === "string")) {
|
|
@@ -136,6 +142,15 @@ function toStringArray(value, option) {
|
|
|
136
142
|
}
|
|
137
143
|
throw new Error(i18n.option_0_must_be_an_array_of_string(option.name));
|
|
138
144
|
}
|
|
145
|
+
function toStringOrFunctionArray(value, option) {
|
|
146
|
+
if (Array.isArray(value) && value.every(v => typeof v === "string" || typeof v === "function")) {
|
|
147
|
+
return value;
|
|
148
|
+
}
|
|
149
|
+
else if (typeof value === "string") {
|
|
150
|
+
return [value];
|
|
151
|
+
}
|
|
152
|
+
throw new Error(i18n.option_0_must_be_an_array_of_string_or_functions(option.name));
|
|
153
|
+
}
|
|
139
154
|
const converters = {
|
|
140
155
|
[ParameterType.String](value, option) {
|
|
141
156
|
// eslint-disable-next-line @typescript-eslint/no-base-to-string
|
|
@@ -183,12 +198,18 @@ const converters = {
|
|
|
183
198
|
option.validate?.(normalized);
|
|
184
199
|
return normalized;
|
|
185
200
|
},
|
|
201
|
+
// eslint-disable-next-line @typescript-eslint/no-deprecated
|
|
186
202
|
[ParameterType.ModuleArray](value, option, configPath) {
|
|
187
203
|
const strArrValue = toStringArray(value, option);
|
|
188
204
|
const resolved = resolveModulePaths(strArrValue, configPath);
|
|
189
205
|
option.validate?.(resolved);
|
|
190
206
|
return resolved;
|
|
191
207
|
},
|
|
208
|
+
[ParameterType.PluginArray](value, option, configPath) {
|
|
209
|
+
const arrayValue = toStringOrFunctionArray(value, option);
|
|
210
|
+
const resolved = arrayValue.map(plugin => typeof plugin === "function" ? plugin : resolveModulePath(plugin, configPath));
|
|
211
|
+
return resolved;
|
|
212
|
+
},
|
|
192
213
|
[ParameterType.GlobArray](value, option, configPath) {
|
|
193
214
|
const toGlobString = (v) => {
|
|
194
215
|
const s = String(v);
|
|
@@ -321,12 +342,19 @@ const defaultGetters = {
|
|
|
321
342
|
[ParameterType.PathArray](option) {
|
|
322
343
|
return (option.defaultValue?.map((value) => normalizePath(resolve(process.cwd(), value))) ?? []);
|
|
323
344
|
},
|
|
345
|
+
// eslint-disable-next-line @typescript-eslint/no-deprecated
|
|
324
346
|
[ParameterType.ModuleArray](option) {
|
|
325
347
|
if (option.defaultValue) {
|
|
326
348
|
return resolveModulePaths(option.defaultValue, process.cwd());
|
|
327
349
|
}
|
|
328
350
|
return [];
|
|
329
351
|
},
|
|
352
|
+
[ParameterType.PluginArray](option) {
|
|
353
|
+
if (option.defaultValue) {
|
|
354
|
+
return resolveModulePaths(option.defaultValue, process.cwd());
|
|
355
|
+
}
|
|
356
|
+
return [];
|
|
357
|
+
},
|
|
330
358
|
[ParameterType.GlobArray](option) {
|
|
331
359
|
return (option.defaultValue ?? []).map(g => createGlobString(normalizePath(process.cwd()), g));
|
|
332
360
|
},
|
|
@@ -339,12 +367,13 @@ export function getDefaultValue(option) {
|
|
|
339
367
|
return getters[option.type ?? ParameterType.String](option);
|
|
340
368
|
}
|
|
341
369
|
function resolveModulePaths(modules, configPath) {
|
|
342
|
-
return modules.map(
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
return normalizePath(path);
|
|
347
|
-
}
|
|
370
|
+
return modules.map(path => resolveModulePath(path, configPath));
|
|
371
|
+
}
|
|
372
|
+
function resolveModulePath(path, configPath) {
|
|
373
|
+
if (path.startsWith(".")) {
|
|
374
|
+
return normalizePath(resolve(configPath, path));
|
|
375
|
+
}
|
|
376
|
+
return normalizePath(path);
|
|
348
377
|
}
|
|
349
378
|
function isTsNumericEnum(map) {
|
|
350
379
|
return Object.values(map).every((key) => map[map[key]] === key);
|
|
@@ -4,7 +4,9 @@ import { i18n } from "#utils";
|
|
|
4
4
|
const ARRAY_OPTION_TYPES = new Set([
|
|
5
5
|
ParameterType.Array,
|
|
6
6
|
ParameterType.PathArray,
|
|
7
|
+
// eslint-disable-next-line @typescript-eslint/no-deprecated
|
|
7
8
|
ParameterType.ModuleArray,
|
|
9
|
+
ParameterType.PluginArray,
|
|
8
10
|
ParameterType.GlobArray,
|
|
9
11
|
]);
|
|
10
12
|
/**
|
|
@@ -801,7 +801,7 @@ export function addTypeDocOptions(options) {
|
|
|
801
801
|
options.addDeclaration({
|
|
802
802
|
name: "plugin",
|
|
803
803
|
help: () => i18n.help_plugin(),
|
|
804
|
-
type: ParameterType.
|
|
804
|
+
type: ParameterType.PluginArray,
|
|
805
805
|
});
|
|
806
806
|
options.addDeclaration({
|
|
807
807
|
name: "logLevel",
|
|
@@ -1,2 +1,3 @@
|
|
|
1
1
|
import type { Application } from "../application.js";
|
|
2
|
-
|
|
2
|
+
import { type NormalizedPathOrModuleOrFunction } from "#utils";
|
|
3
|
+
export declare function loadPlugins(app: Application, plugins: readonly NormalizedPathOrModuleOrFunction[]): Promise<void>;
|
|
@@ -6,27 +6,33 @@ export async function loadPlugins(app, plugins) {
|
|
|
6
6
|
for (const plugin of plugins) {
|
|
7
7
|
const pluginDisplay = getPluginDisplayName(plugin);
|
|
8
8
|
try {
|
|
9
|
-
let
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
try {
|
|
13
|
-
// On Windows, we need to ensure this path is a file path.
|
|
14
|
-
// Or we'll get ERR_UNSUPPORTED_ESM_URL_SCHEME
|
|
15
|
-
const esmPath = isAbsolute(plugin)
|
|
16
|
-
? pathToFileURL(plugin).toString()
|
|
17
|
-
: plugin;
|
|
18
|
-
instance = await import(esmPath);
|
|
9
|
+
let initFunction;
|
|
10
|
+
if (typeof plugin === "function") {
|
|
11
|
+
initFunction = plugin;
|
|
19
12
|
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
13
|
+
else {
|
|
14
|
+
let instance;
|
|
15
|
+
// Try importing first to avoid warnings about requiring ESM being experimental.
|
|
16
|
+
// If that fails due to importing a directory, fall back to require.
|
|
17
|
+
try {
|
|
18
|
+
// On Windows, we need to ensure this path is a file path.
|
|
19
|
+
// Or we'll get ERR_UNSUPPORTED_ESM_URL_SCHEME
|
|
20
|
+
const esmPath = isAbsolute(plugin)
|
|
21
|
+
? pathToFileURL(plugin).toString()
|
|
22
|
+
: plugin;
|
|
23
|
+
instance = await import(esmPath);
|
|
24
24
|
}
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
catch (error) {
|
|
26
|
+
if (error.code === "ERR_UNSUPPORTED_DIR_IMPORT") {
|
|
27
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
28
|
+
instance = require(plugin);
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
throw error;
|
|
32
|
+
}
|
|
27
33
|
}
|
|
34
|
+
initFunction = instance.load;
|
|
28
35
|
}
|
|
29
|
-
const initFunction = instance.load;
|
|
30
36
|
if (typeof initFunction === "function") {
|
|
31
37
|
await initFunction(app);
|
|
32
38
|
app.logger.info(i18n.loaded_plugin_0(pluginDisplay));
|
|
@@ -44,6 +50,9 @@ export async function loadPlugins(app, plugins) {
|
|
|
44
50
|
}
|
|
45
51
|
}
|
|
46
52
|
function getPluginDisplayName(plugin) {
|
|
53
|
+
if (typeof plugin === "function") {
|
|
54
|
+
return plugin.name || "function";
|
|
55
|
+
}
|
|
47
56
|
const path = nicePath(plugin);
|
|
48
57
|
if (path.startsWith("./node_modules/")) {
|
|
49
58
|
return path.substring("./node_modules/".length);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { Application } from "../application.js";
|
|
1
2
|
/**
|
|
2
3
|
* Represents a normalized path with path separators being `/`
|
|
3
4
|
* On Windows, drives are represented like `C:/Users` for consistency
|
|
@@ -15,6 +16,11 @@ export type NormalizedPath = "" | "/" | string & {
|
|
|
15
16
|
export type NormalizedPathOrModule = NormalizedPath | string & {
|
|
16
17
|
readonly __normPathOrModule: unique symbol;
|
|
17
18
|
};
|
|
19
|
+
/**
|
|
20
|
+
* Represents either a {@link NormalizedPath} or a Node module name
|
|
21
|
+
* (e.g. `typedoc-plugin-mdn-links` or `@gerrit0/typedoc-plugin`)
|
|
22
|
+
*/
|
|
23
|
+
export type NormalizedPathOrModuleOrFunction = NormalizedPathOrModule | ((app: Application) => Promise<void> | void);
|
|
18
24
|
/**
|
|
19
25
|
* Represents a glob path configured by a user.
|
|
20
26
|
*/
|