typedoc 0.24.0-beta.3 → 0.24.0-beta.4

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.
Files changed (41) hide show
  1. package/README.md +1 -1
  2. package/dist/lib/cli.js +5 -2
  3. package/dist/lib/converter/comments/blockLexer.d.ts +2 -1
  4. package/dist/lib/converter/comments/blockLexer.js +45 -4
  5. package/dist/lib/converter/comments/discovery.d.ts +7 -2
  6. package/dist/lib/converter/comments/discovery.js +37 -5
  7. package/dist/lib/converter/comments/index.d.ts +3 -3
  8. package/dist/lib/converter/comments/index.js +18 -17
  9. package/dist/lib/converter/comments/lexer.d.ts +2 -0
  10. package/dist/lib/converter/comments/linkResolver.d.ts +2 -2
  11. package/dist/lib/converter/comments/linkResolver.js +25 -20
  12. package/dist/lib/converter/comments/parser.js +6 -2
  13. package/dist/lib/converter/context.d.ts +1 -1
  14. package/dist/lib/converter/context.js +2 -2
  15. package/dist/lib/converter/converter.d.ts +2 -0
  16. package/dist/lib/converter/converter.js +6 -3
  17. package/dist/lib/converter/factories/signature.js +16 -7
  18. package/dist/lib/converter/jsdoc.js +3 -3
  19. package/dist/lib/converter/plugins/InheritDocPlugin.js +2 -1
  20. package/dist/lib/converter/symbols.js +7 -5
  21. package/dist/lib/models/comments/comment.d.ts +6 -6
  22. package/dist/lib/models/comments/comment.js +26 -10
  23. package/dist/lib/models/reflections/abstract.js +1 -1
  24. package/dist/lib/models/reflections/project.js +1 -1
  25. package/dist/lib/output/events.js +4 -4
  26. package/dist/lib/output/themes/default/DefaultTheme.js +7 -1
  27. package/dist/lib/output/themes/default/partials/typeParameters.js +1 -0
  28. package/dist/lib/output/themes/default/templates/reflection.js +2 -1
  29. package/dist/lib/output/themes/lib.js +1 -0
  30. package/dist/lib/serialization/schema.d.ts +8 -7
  31. package/dist/lib/serialization/serializer.js +1 -1
  32. package/dist/lib/utils/component.js +1 -1
  33. package/dist/lib/utils/entry-point.js +2 -2
  34. package/dist/lib/utils/options/declaration.d.ts +2 -0
  35. package/dist/lib/utils/options/sources/typedoc.js +19 -2
  36. package/dist/lib/utils/options/tsdoc-defaults.d.ts +2 -2
  37. package/dist/lib/utils/options/tsdoc-defaults.js +2 -0
  38. package/dist/lib/utils/package-manifest.js +4 -4
  39. package/package.json +8 -8
  40. package/static/style.css +4 -5
  41. package/tsdoc.json +16 -0
package/README.md CHANGED
@@ -41,7 +41,7 @@ By default, TypeDoc will search for a file called `index` under the directory.
41
41
  If your codebase is comprised of one or more npm packages, you can build documentation for each of them individually
42
42
  and merge the results together into a single site by setting `entryPointStrategy` to `packages`. In this mode TypeDoc
43
43
  requires configuration to be present in each directory to specify the entry points. For an example setup, see
44
- `<TODO need to create example>`
44
+ https://github.com/Gerrit0/typedoc-packages-example
45
45
 
46
46
  ### Arguments
47
47
 
package/dist/lib/cli.js CHANGED
@@ -93,12 +93,15 @@ async function run(app) {
93
93
  app.logger.hasWarnings()) {
94
94
  return ExitCodes.CompileError;
95
95
  }
96
+ const preValidationWarnCount = app.logger.warningCount;
96
97
  app.validate(project);
98
+ const hadValidationWarnings = app.logger.warningCount !== preValidationWarnCount;
97
99
  if (app.logger.hasErrors()) {
98
100
  return ExitCodes.ValidationError;
99
101
  }
100
- if (app.options.getValue("treatWarningsAsErrors") &&
101
- app.logger.hasWarnings()) {
102
+ if (hadValidationWarnings &&
103
+ (app.options.getValue("treatWarningsAsErrors") ||
104
+ app.options.getValue("treatValidationWarningsAsErrors"))) {
102
105
  return ExitCodes.ValidationError;
103
106
  }
104
107
  if (app.options.getValue("emit") !== "none") {
@@ -1,2 +1,3 @@
1
+ import ts from "typescript";
1
2
  import { Token } from "./lexer";
2
- export declare function lexBlockComment(file: string, pos?: number, end?: number): Generator<Token, undefined, undefined>;
3
+ export declare function lexBlockComment(file: string, pos?: number, end?: number, jsDoc?: ts.JSDoc | undefined, checker?: ts.TypeChecker | undefined): Generator<Token, undefined, undefined>;
@@ -1,11 +1,17 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.lexBlockComment = void 0;
7
+ const typescript_1 = __importDefault(require("typescript"));
4
8
  const lexer_1 = require("./lexer");
5
- function* lexBlockComment(file, pos = 0, end = file.length) {
9
+ const ReflectionSymbolId_1 = require("../../models/reflections/ReflectionSymbolId");
10
+ const symbols_1 = require("../utils/symbols");
11
+ function* lexBlockComment(file, pos = 0, end = file.length, jsDoc = undefined, checker = undefined) {
6
12
  // Wrapper around our real lex function to collapse adjacent text tokens.
7
13
  let textToken;
8
- for (const token of lexBlockComment2(file, pos, end)) {
14
+ for (const token of lexBlockComment2(file, pos, end, getLinkTags(jsDoc), checker)) {
9
15
  if (token.kind === lexer_1.TokenSyntaxKind.Text) {
10
16
  if (textToken) {
11
17
  textToken.text += token.text;
@@ -28,7 +34,21 @@ function* lexBlockComment(file, pos = 0, end = file.length) {
28
34
  return;
29
35
  }
30
36
  exports.lexBlockComment = lexBlockComment;
31
- function* lexBlockComment2(file, pos, end) {
37
+ function getLinkTags(jsDoc) {
38
+ const result = [];
39
+ if (!jsDoc || typeof jsDoc.comment !== "object")
40
+ return result;
41
+ for (const part of jsDoc.comment) {
42
+ switch (part.kind) {
43
+ case typescript_1.default.SyntaxKind.JSDocLink:
44
+ case typescript_1.default.SyntaxKind.JSDocLinkCode:
45
+ case typescript_1.default.SyntaxKind.JSDocLinkPlain:
46
+ result.push(part);
47
+ }
48
+ }
49
+ return result;
50
+ }
51
+ function* lexBlockComment2(file, pos, end, linkTags, checker) {
32
52
  pos += 2; // Leading '/*'
33
53
  end -= 2; // Trailing '*/'
34
54
  if (pos < end && file[pos] === "*") {
@@ -47,6 +67,7 @@ function* lexBlockComment2(file, pos, end) {
47
67
  }
48
68
  let lineStart = true;
49
69
  let braceStartsType = false;
70
+ let linkTagIndex = 0;
50
71
  for (;;) {
51
72
  if (pos >= end) {
52
73
  return;
@@ -171,7 +192,9 @@ function* lexBlockComment2(file, pos, end) {
171
192
  if (lookahead !== pos + 1 &&
172
193
  (lookahead === end || /\s/.test(file[lookahead]))) {
173
194
  braceStartsType = true;
174
- yield makeToken(lexer_1.TokenSyntaxKind.Tag, lookahead - pos);
195
+ const token = makeToken(lexer_1.TokenSyntaxKind.Tag, lookahead - pos);
196
+ attachLinkTagResult(token);
197
+ yield token;
175
198
  break;
176
199
  }
177
200
  }
@@ -213,6 +236,24 @@ function* lexBlockComment2(file, pos, end) {
213
236
  }
214
237
  }
215
238
  }
239
+ function attachLinkTagResult(token) {
240
+ // We might need to skip link tags if someone has link tags inside of an example comment
241
+ // pos-1 for opening brace, TS doesn't allow spaces between opening brace and @ sign as of 5.0.2
242
+ while (linkTagIndex < linkTags.length &&
243
+ linkTags[linkTagIndex].pos < token.pos - 1) {
244
+ linkTagIndex++;
245
+ }
246
+ if (linkTagIndex < linkTags.length &&
247
+ linkTags[linkTagIndex].pos === token.pos - 1) {
248
+ const link = linkTags[linkTagIndex];
249
+ if (link.name) {
250
+ const tsTarget = checker?.getSymbolAtLocation(link.name);
251
+ if (tsTarget) {
252
+ token.linkTarget = new ReflectionSymbolId_1.ReflectionSymbolId((0, symbols_1.resolveAliasedSymbol)(tsTarget, checker));
253
+ }
254
+ }
255
+ }
256
+ }
216
257
  function makeToken(kind, size) {
217
258
  const start = pos;
218
259
  pos += size;
@@ -2,5 +2,10 @@ import ts from "typescript";
2
2
  import { ReflectionKind } from "../../models";
3
3
  import { Logger } from "../../utils";
4
4
  import { CommentStyle } from "../../utils/options/declaration";
5
- export declare function discoverComment(symbol: ts.Symbol, kind: ReflectionKind, logger: Logger, commentStyle: CommentStyle): [ts.SourceFile, ts.CommentRange[]] | undefined;
6
- export declare function discoverSignatureComment(declaration: ts.SignatureDeclaration | ts.JSDocSignature, commentStyle: CommentStyle): [ts.SourceFile, ts.CommentRange[]] | undefined;
5
+ export interface DiscoveredComment {
6
+ file: ts.SourceFile;
7
+ ranges: ts.CommentRange[];
8
+ jsDoc: ts.JSDoc | undefined;
9
+ }
10
+ export declare function discoverComment(symbol: ts.Symbol, kind: ReflectionKind, logger: Logger, commentStyle: CommentStyle): DiscoveredComment | undefined;
11
+ export declare function discoverSignatureComment(declaration: ts.SignatureDeclaration | ts.JSDocSignature, commentStyle: CommentStyle): DiscoveredComment | undefined;
@@ -9,6 +9,7 @@ const models_1 = require("../../models");
9
9
  const utils_1 = require("../../utils");
10
10
  const declaration_1 = require("../../utils/options/declaration");
11
11
  const paths_1 = require("../../utils/paths");
12
+ const assert_1 = require("assert");
12
13
  // Note: This does NOT include JSDoc syntax kinds. This is important!
13
14
  // Comments from @typedef and @callback tags are handled specially by
14
15
  // the JSDoc converter because we only want part of the comment when
@@ -120,7 +121,11 @@ function discoverComment(symbol, kind, logger, commentStyle) {
120
121
  }
121
122
  const selectedDocComment = comments.find((ranges) => permittedRange(text, ranges, commentStyle));
122
123
  if (selectedDocComment) {
123
- discovered.push([decl.getSourceFile(), selectedDocComment]);
124
+ discovered.push({
125
+ file: decl.getSourceFile(),
126
+ ranges: selectedDocComment,
127
+ jsDoc: findJsDocForComment(node, selectedDocComment),
128
+ });
124
129
  }
125
130
  }
126
131
  }
@@ -131,9 +136,9 @@ function discoverComment(symbol, kind, logger, commentStyle) {
131
136
  return discovered[0];
132
137
  default: {
133
138
  logger.warn(`${symbol.name} has multiple declarations with a comment. An arbitrary comment will be used.`);
134
- const locations = discovered.map(([sf, [{ pos }]]) => {
135
- const path = (0, paths_1.nicePath)(sf.fileName);
136
- const line = typescript_1.default.getLineAndCharacterOfPosition(sf, pos).line + 1;
139
+ const locations = discovered.map(({ file, ranges: [{ pos }] }) => {
140
+ const path = (0, paths_1.nicePath)(file.fileName);
141
+ const line = typescript_1.default.getLineAndCharacterOfPosition(file, pos).line + 1;
137
142
  return `${path}:${line}`;
138
143
  });
139
144
  logger.info(`The comments for ${symbol.name} are declared at:\n\t${locations.join("\n\t")}`);
@@ -147,15 +152,42 @@ function discoverSignatureComment(declaration, commentStyle) {
147
152
  if (!node) {
148
153
  return;
149
154
  }
155
+ if (typescript_1.default.isJSDocSignature(node)) {
156
+ const comment = node.parent.parent;
157
+ (0, assert_1.ok)(typescript_1.default.isJSDoc(comment));
158
+ return {
159
+ file: node.getSourceFile(),
160
+ ranges: [
161
+ {
162
+ kind: typescript_1.default.SyntaxKind.MultiLineCommentTrivia,
163
+ pos: comment.pos,
164
+ end: comment.end,
165
+ },
166
+ ],
167
+ jsDoc: undefined,
168
+ };
169
+ }
150
170
  const text = node.getSourceFile().text;
151
171
  const comments = collectCommentRanges(typescript_1.default.getLeadingCommentRanges(text, node.pos));
152
172
  comments.reverse();
153
173
  const comment = comments.find((ranges) => permittedRange(text, ranges, commentStyle));
154
174
  if (comment) {
155
- return [node.getSourceFile(), comment];
175
+ return {
176
+ file: node.getSourceFile(),
177
+ ranges: comment,
178
+ jsDoc: findJsDocForComment(node, comment),
179
+ };
156
180
  }
157
181
  }
158
182
  exports.discoverSignatureComment = discoverSignatureComment;
183
+ function findJsDocForComment(node, ranges) {
184
+ if (ranges[0].kind === typescript_1.default.SyntaxKind.MultiLineCommentTrivia) {
185
+ const jsDocs = typescript_1.default
186
+ .getJSDocCommentsAndTags(node)
187
+ .map((doc) => typescript_1.default.findAncestor(doc, typescript_1.default.isJSDoc));
188
+ return jsDocs.find((doc) => doc.pos === ranges[0].pos);
189
+ }
190
+ }
159
191
  /**
160
192
  * Check whether the given module declaration is the topmost.
161
193
  *
@@ -7,6 +7,6 @@ export interface CommentParserConfig {
7
7
  inlineTags: Set<string>;
8
8
  modifierTags: Set<string>;
9
9
  }
10
- export declare function getComment(symbol: ts.Symbol, kind: ReflectionKind, config: CommentParserConfig, logger: Logger, commentStyle: CommentStyle): Comment | undefined;
11
- export declare function getSignatureComment(declaration: ts.SignatureDeclaration | ts.JSDocSignature, config: CommentParserConfig, logger: Logger, commentStyle: CommentStyle): Comment | undefined;
12
- export declare function getJsDocComment(declaration: ts.JSDocPropertyLikeTag | ts.JSDocCallbackTag | ts.JSDocTypedefTag | ts.JSDocTemplateTag | ts.JSDocEnumTag, config: CommentParserConfig, logger: Logger): Comment | undefined;
10
+ export declare function getComment(symbol: ts.Symbol, kind: ReflectionKind, config: CommentParserConfig, logger: Logger, commentStyle: CommentStyle, checker: ts.TypeChecker): Comment | undefined;
11
+ export declare function getSignatureComment(declaration: ts.SignatureDeclaration | ts.JSDocSignature, config: CommentParserConfig, logger: Logger, commentStyle: CommentStyle, checker: ts.TypeChecker): Comment | undefined;
12
+ export declare function getJsDocComment(declaration: ts.JSDocPropertyLikeTag | ts.JSDocCallbackTag | ts.JSDocTypedefTag | ts.JSDocTemplateTag | ts.JSDocEnumTag, config: CommentParserConfig, logger: Logger, checker: ts.TypeChecker): Comment | undefined;
@@ -19,10 +19,10 @@ const jsDocCommentKinds = [
19
19
  typescript_1.default.SyntaxKind.JSDocEnumTag,
20
20
  ];
21
21
  const commentCache = new WeakMap();
22
- function getCommentWithCache(discovered, config, logger) {
22
+ function getCommentWithCache(discovered, config, logger, checker) {
23
23
  if (!discovered)
24
24
  return;
25
- const [file, ranges] = discovered;
25
+ const { file, ranges, jsDoc } = discovered;
26
26
  const cache = commentCache.get(file) || new Map();
27
27
  if (cache?.has(ranges[0].pos)) {
28
28
  return cache.get(ranges[0].pos).clone();
@@ -30,7 +30,7 @@ function getCommentWithCache(discovered, config, logger) {
30
30
  let comment;
31
31
  switch (ranges[0].kind) {
32
32
  case typescript_1.default.SyntaxKind.MultiLineCommentTrivia:
33
- comment = (0, parser_1.parseComment)((0, blockLexer_1.lexBlockComment)(file.text, ranges[0].pos, ranges[0].end), config, file, logger);
33
+ comment = (0, parser_1.parseComment)((0, blockLexer_1.lexBlockComment)(file.text, ranges[0].pos, ranges[0].end, jsDoc, checker), config, file, logger);
34
34
  break;
35
35
  case typescript_1.default.SyntaxKind.SingleLineCommentTrivia:
36
36
  comment = (0, parser_1.parseComment)((0, lineLexer_1.lexLineComments)(file.text, ranges), config, file, logger);
@@ -42,8 +42,8 @@ function getCommentWithCache(discovered, config, logger) {
42
42
  commentCache.set(file, cache);
43
43
  return comment.clone();
44
44
  }
45
- function getCommentImpl(commentSource, config, logger, moduleComment) {
46
- const comment = getCommentWithCache(commentSource, config, logger);
45
+ function getCommentImpl(commentSource, config, logger, moduleComment, checker) {
46
+ const comment = getCommentWithCache(commentSource, config, logger, checker);
47
47
  if (moduleComment && comment) {
48
48
  // Module comment, make sure it is tagged with @packageDocumentation or @module.
49
49
  // If it isn't then the comment applies to the first statement in the file, so throw it away.
@@ -61,35 +61,35 @@ function getCommentImpl(commentSource, config, logger, moduleComment) {
61
61
  }
62
62
  return comment;
63
63
  }
64
- function getComment(symbol, kind, config, logger, commentStyle) {
64
+ function getComment(symbol, kind, config, logger, commentStyle, checker) {
65
65
  const declarations = symbol.declarations || [];
66
66
  if (declarations.length &&
67
67
  declarations.every((d) => jsDocCommentKinds.includes(d.kind))) {
68
- return getJsDocComment(declarations[0], config, logger);
68
+ return getJsDocComment(declarations[0], config, logger, checker);
69
69
  }
70
- const comment = getCommentImpl((0, discovery_1.discoverComment)(symbol, kind, logger, commentStyle), config, logger, declarations.some(typescript_1.default.isSourceFile));
70
+ const comment = getCommentImpl((0, discovery_1.discoverComment)(symbol, kind, logger, commentStyle), config, logger, declarations.some(typescript_1.default.isSourceFile), checker);
71
71
  if (!comment && kind === models_1.ReflectionKind.Property) {
72
- return getConstructorParamPropertyComment(symbol, config, logger, commentStyle);
72
+ return getConstructorParamPropertyComment(symbol, config, logger, commentStyle, checker);
73
73
  }
74
74
  return comment;
75
75
  }
76
76
  exports.getComment = getComment;
77
- function getConstructorParamPropertyComment(symbol, config, logger, commentStyle) {
77
+ function getConstructorParamPropertyComment(symbol, config, logger, commentStyle, checker) {
78
78
  const decl = symbol.declarations?.find(typescript_1.default.isParameter);
79
79
  if (!decl)
80
80
  return;
81
81
  const ctor = decl.parent;
82
- const comment = getSignatureComment(ctor, config, logger, commentStyle);
82
+ const comment = getSignatureComment(ctor, config, logger, commentStyle, checker);
83
83
  const paramTag = comment?.getIdentifiedTag(symbol.name, "@param");
84
84
  if (paramTag) {
85
85
  return new models_1.Comment(paramTag.content);
86
86
  }
87
87
  }
88
- function getSignatureComment(declaration, config, logger, commentStyle) {
89
- return getCommentImpl((0, discovery_1.discoverSignatureComment)(declaration, commentStyle), config, logger, false);
88
+ function getSignatureComment(declaration, config, logger, commentStyle, checker) {
89
+ return getCommentImpl((0, discovery_1.discoverSignatureComment)(declaration, commentStyle), config, logger, false, checker);
90
90
  }
91
91
  exports.getSignatureComment = getSignatureComment;
92
- function getJsDocComment(declaration, config, logger) {
92
+ function getJsDocComment(declaration, config, logger, checker) {
93
93
  const file = declaration.getSourceFile();
94
94
  // First, get the whole comment. We know we'll need all of it.
95
95
  let parent = declaration.parent;
@@ -97,16 +97,17 @@ function getJsDocComment(declaration, config, logger) {
97
97
  parent = parent.parent;
98
98
  }
99
99
  // Then parse it.
100
- const comment = getCommentWithCache([
100
+ const comment = getCommentWithCache({
101
101
  file,
102
- [
102
+ ranges: [
103
103
  {
104
104
  kind: typescript_1.default.SyntaxKind.MultiLineCommentTrivia,
105
105
  pos: parent.pos,
106
106
  end: parent.end,
107
107
  },
108
108
  ],
109
- ], config, logger);
109
+ jsDoc: parent,
110
+ }, config, logger, checker);
110
111
  // And pull out the tag we actually care about.
111
112
  if (typescript_1.default.isJSDocEnumTag(declaration)) {
112
113
  return new models_1.Comment(comment.getTag("@enum")?.content);
@@ -1,3 +1,4 @@
1
+ import type { ReflectionSymbolId } from "../../models";
1
2
  export declare enum TokenSyntaxKind {
2
3
  Text = "text",
3
4
  NewLine = "new_line",
@@ -11,4 +12,5 @@ export interface Token {
11
12
  kind: TokenSyntaxKind;
12
13
  text: string;
13
14
  pos: number;
15
+ linkTarget?: ReflectionSymbolId;
14
16
  }
@@ -5,5 +5,5 @@ export type ExternalResolveResult = {
5
5
  caption?: string;
6
6
  };
7
7
  export type ExternalSymbolResolver = (ref: DeclarationReference, refl: Reflection, part: Readonly<CommentDisplayPart> | undefined) => ExternalResolveResult | string | undefined;
8
- export declare function resolveLinks(comment: Comment, reflection: Reflection, externalResolver: ExternalSymbolResolver): void;
9
- export declare function resolvePartLinks(reflection: Reflection, parts: readonly CommentDisplayPart[], externalResolver: ExternalSymbolResolver): CommentDisplayPart[];
8
+ export declare function resolveLinks(comment: Comment, reflection: Reflection, externalResolver: ExternalSymbolResolver, useTsResolution: boolean): void;
9
+ export declare function resolvePartLinks(reflection: Reflection, parts: readonly CommentDisplayPart[], externalResolver: ExternalSymbolResolver, useTsResolution: boolean): CommentDisplayPart[];
@@ -9,40 +9,48 @@ const models_1 = require("../../models");
9
9
  const declarationReference_1 = require("./declarationReference");
10
10
  const declarationReferenceResolver_1 = require("./declarationReferenceResolver");
11
11
  const urlPrefix = /^(http|ftp)s?:\/\//;
12
- function resolveLinks(comment, reflection, externalResolver) {
13
- comment.summary = resolvePartLinks(reflection, comment.summary, externalResolver);
12
+ function resolveLinks(comment, reflection, externalResolver, useTsResolution) {
13
+ comment.summary = resolvePartLinks(reflection, comment.summary, externalResolver, useTsResolution);
14
14
  for (const tag of comment.blockTags) {
15
- tag.content = resolvePartLinks(reflection, tag.content, externalResolver);
15
+ tag.content = resolvePartLinks(reflection, tag.content, externalResolver, useTsResolution);
16
16
  }
17
17
  if (reflection instanceof models_1.DeclarationReflection && reflection.readme) {
18
- reflection.readme = resolvePartLinks(reflection, reflection.readme, externalResolver);
18
+ reflection.readme = resolvePartLinks(reflection, reflection.readme, externalResolver, useTsResolution);
19
19
  }
20
20
  }
21
21
  exports.resolveLinks = resolveLinks;
22
- function resolvePartLinks(reflection, parts, externalResolver) {
23
- return parts.flatMap((part) => processPart(reflection, part, externalResolver));
22
+ function resolvePartLinks(reflection, parts, externalResolver, useTsResolution) {
23
+ return parts.flatMap((part) => processPart(reflection, part, externalResolver, useTsResolution));
24
24
  }
25
25
  exports.resolvePartLinks = resolvePartLinks;
26
- function processPart(reflection, part, externalResolver) {
26
+ function processPart(reflection, part, externalResolver, useTsResolution) {
27
27
  if (part.kind === "inline-tag") {
28
28
  if (part.tag === "@link" ||
29
29
  part.tag === "@linkcode" ||
30
30
  part.tag === "@linkplain") {
31
- return resolveLinkTag(reflection, part, externalResolver);
31
+ return resolveLinkTag(reflection, part, externalResolver, useTsResolution);
32
32
  }
33
33
  }
34
34
  return part;
35
35
  }
36
- function resolveLinkTag(reflection, part, externalResolver) {
36
+ function resolveLinkTag(reflection, part, externalResolver, useTsResolution) {
37
+ let defaultDisplayText = "";
37
38
  let pos = 0;
38
39
  const end = part.text.length;
39
40
  while (pos < end && typescript_1.default.isWhiteSpaceLike(part.text.charCodeAt(pos))) {
40
41
  pos++;
41
42
  }
42
- // Try to parse one
43
- const declRef = (0, declarationReference_1.parseDeclarationReference)(part.text, pos, end);
44
43
  let target;
45
- let defaultDisplayText = "";
44
+ if (useTsResolution && part.target instanceof models_1.ReflectionSymbolId) {
45
+ target = reflection.project.getReflectionFromSymbolId(part.target);
46
+ if (target) {
47
+ pos = end;
48
+ defaultDisplayText =
49
+ part.text.replace(/^\s*[A-Z_$][\w$]*[ |]*/i, "") || target.name;
50
+ }
51
+ }
52
+ // Try to parse a declaration reference if we didn't use the TS symbol for resolution
53
+ const declRef = !target && (0, declarationReference_1.parseDeclarationReference)(part.text, pos, end);
46
54
  if (declRef) {
47
55
  // Got one, great! Try to resolve the link
48
56
  target = (0, declarationReferenceResolver_1.resolveDeclarationReference)(reflection, declRef[0]);
@@ -65,14 +73,11 @@ function resolveLinkTag(reflection, part, externalResolver) {
65
73
  }
66
74
  }
67
75
  }
68
- if (!target) {
69
- if (urlPrefix.test(part.text)) {
70
- const wsIndex = part.text.search(/\s/);
71
- target =
72
- wsIndex === -1 ? part.text : part.text.substring(0, wsIndex);
73
- pos = target.length;
74
- defaultDisplayText = target;
75
- }
76
+ if (!target && urlPrefix.test(part.text)) {
77
+ const wsIndex = part.text.search(/\s/);
78
+ target = wsIndex === -1 ? part.text : part.text.substring(0, wsIndex);
79
+ pos = target.length;
80
+ defaultDisplayText = target;
76
81
  }
77
82
  // Remaining text after an optional pipe is the link text, so advance
78
83
  // until that's consumed.
@@ -299,9 +299,13 @@ function inlineTag(lexer, block, config, warning) {
299
299
  else {
300
300
  lexer.take(); // Close brace
301
301
  }
302
- block.push({
302
+ const inlineTag = {
303
303
  kind: "inline-tag",
304
304
  tag: tagName.text,
305
305
  text: content.join(""),
306
- });
306
+ };
307
+ if (tagName.linkTarget) {
308
+ inlineTag.target = tagName.linkTarget;
309
+ }
310
+ block.push(inlineTag);
307
311
  }
@@ -46,7 +46,7 @@ export declare class Context {
46
46
  */
47
47
  constructor(converter: Converter, programs: readonly ts.Program[], project: ProjectReflection, scope?: Context["scope"]);
48
48
  /** @internal */
49
- get logger(): import("../utils/loggers").Logger;
49
+ get logger(): import("../utils").Logger;
50
50
  /**
51
51
  * Return the compiler options.
52
52
  */
@@ -120,10 +120,10 @@ class Context {
120
120
  if (exportSymbol &&
121
121
  reflection.kind &
122
122
  (index_1.ReflectionKind.SomeModule | index_1.ReflectionKind.Reference)) {
123
- reflection.comment = (0, comments_1.getComment)(exportSymbol, reflection.kind, this.converter.config, this.logger, this.converter.commentStyle);
123
+ reflection.comment = (0, comments_1.getComment)(exportSymbol, reflection.kind, this.converter.config, this.logger, this.converter.commentStyle, this.checker);
124
124
  }
125
125
  if (symbol && !reflection.comment) {
126
- reflection.comment = (0, comments_1.getComment)(symbol, reflection.kind, this.converter.config, this.logger, this.converter.commentStyle);
126
+ reflection.comment = (0, comments_1.getComment)(symbol, reflection.kind, this.converter.config, this.logger, this.converter.commentStyle, this.checker);
127
127
  }
128
128
  if (this.shouldBeStatic) {
129
129
  reflection.setFlag(index_1.ReflectionFlag.Static);
@@ -32,6 +32,8 @@ export declare class Converter extends ChildableComponent<Application, Converter
32
32
  validation: ValidationOptions;
33
33
  /** @internal */
34
34
  externalSymbolLinkMappings: Record<string, Record<string, string>>;
35
+ /** @internal */
36
+ useTsLinkResolution: boolean;
35
37
  private _config?;
36
38
  private _externalSymbolResolvers;
37
39
  get config(): CommentParserConfig;
@@ -123,10 +123,10 @@ let Converter = Converter_1 = class Converter extends component_1.ChildableCompo
123
123
  }
124
124
  resolveLinks(comment, owner) {
125
125
  if (comment instanceof index_1.Comment) {
126
- (0, linkResolver_1.resolveLinks)(comment, owner, (ref, part, refl) => this.resolveExternalLink(ref, part, refl));
126
+ (0, linkResolver_1.resolveLinks)(comment, owner, (ref, part, refl) => this.resolveExternalLink(ref, part, refl), this.useTsLinkResolution);
127
127
  }
128
128
  else {
129
- return (0, linkResolver_1.resolvePartLinks)(owner, comment, (ref, part, refl) => this.resolveExternalLink(ref, part, refl));
129
+ return (0, linkResolver_1.resolvePartLinks)(owner, comment, (ref, part, refl) => this.resolveExternalLink(ref, part, refl), this.useTsLinkResolution);
130
130
  }
131
131
  }
132
132
  /**
@@ -166,7 +166,7 @@ let Converter = Converter_1 = class Converter extends component_1.ChildableCompo
166
166
  context.project.registerReflection(context.project, symbol);
167
167
  context.project.comment =
168
168
  symbol &&
169
- (0, comments_1.getComment)(symbol, context.project.kind, this.config, this.application.logger, this.commentStyle);
169
+ (0, comments_1.getComment)(symbol, context.project.kind, this.config, this.application.logger, this.commentStyle, context.checker);
170
170
  context.trigger(Converter_1.EVENT_CREATE_DECLARATION, context.project);
171
171
  moduleContext = context;
172
172
  }
@@ -334,6 +334,9 @@ __decorate([
334
334
  __decorate([
335
335
  (0, utils_1.BindOption)("externalSymbolLinkMappings")
336
336
  ], Converter.prototype, "externalSymbolLinkMappings", void 0);
337
+ __decorate([
338
+ (0, utils_1.BindOption)("useTsLinkResolution")
339
+ ], Converter.prototype, "useTsLinkResolution", void 0);
337
340
  Converter = Converter_1 = __decorate([
338
341
  (0, component_1.Component)({
339
342
  name: "converter",
@@ -35,7 +35,7 @@ function createSignature(context, kind, signature, symbol, declaration) {
35
35
  (!parentReflection.comment ||
36
36
  !(parentReflection.conversionFlags &
37
37
  models_1.ConversionFlags.VariableOrPropertySource))) {
38
- sigRef.comment = (0, comments_1.getSignatureComment)(declaration, context.converter.config, context.logger, context.converter.commentStyle);
38
+ sigRef.comment = (0, comments_1.getSignatureComment)(declaration, context.converter.config, context.logger, context.converter.commentStyle, context.checker);
39
39
  }
40
40
  sigRef.typeParameters = convertTypeParameters(sigRefCtx, sigRef, signature.typeParameters);
41
41
  const parameterSymbols = signature.thisParameter
@@ -79,9 +79,9 @@ function convertParameters(context, sigRef, parameters, parameterNodes) {
79
79
  typescript_1.default.isJSDocParameterTag(declaration));
80
80
  const paramRefl = new models_1.ParameterReflection(/__\d+/.test(param.name) ? "__namedParameters" : param.name, models_1.ReflectionKind.Parameter, sigRef);
81
81
  if (declaration && typescript_1.default.isJSDocParameterTag(declaration)) {
82
- paramRefl.comment = (0, comments_1.getJsDocComment)(declaration, context.converter.config, context.logger);
82
+ paramRefl.comment = (0, comments_1.getJsDocComment)(declaration, context.converter.config, context.logger, context.checker);
83
83
  }
84
- paramRefl.comment || (paramRefl.comment = (0, comments_1.getComment)(param, paramRefl.kind, context.converter.config, context.logger, context.converter.commentStyle));
84
+ paramRefl.comment || (paramRefl.comment = (0, comments_1.getComment)(param, paramRefl.kind, context.converter.config, context.logger, context.converter.commentStyle, context.checker));
85
85
  context.registerReflection(paramRefl, param);
86
86
  context.trigger(converter_events_1.ConverterEvents.CREATE_PARAMETER, paramRefl);
87
87
  let type;
@@ -125,7 +125,7 @@ function convertParameterNodes(context, sigRef, parameters) {
125
125
  ? "__namedParameters"
126
126
  : param.name.getText(), models_1.ReflectionKind.Parameter, sigRef);
127
127
  if (typescript_1.default.isJSDocParameterTag(param)) {
128
- paramRefl.comment = (0, comments_1.getJsDocComment)(param, context.converter.config, context.logger);
128
+ paramRefl.comment = (0, comments_1.getJsDocComment)(param, context.converter.config, context.logger, context.checker);
129
129
  }
130
130
  context.registerReflection(paramRefl, context.getSymbolAtLocation(param));
131
131
  context.trigger(converter_events_1.ConverterEvents.CREATE_PARAMETER, paramRefl);
@@ -152,8 +152,10 @@ function convertTypeParameters(context, parent, parameters) {
152
152
  const defaultT = param.getDefault();
153
153
  // There's no way to determine directly from a ts.TypeParameter what it's variance modifiers are
154
154
  // so unfortunately we have to go back to the node for this...
155
- const variance = getVariance(param.getSymbol()?.declarations?.find(typescript_1.default.isTypeParameterDeclaration)
156
- ?.modifiers);
155
+ const declaration = param
156
+ .getSymbol()
157
+ ?.declarations?.find(typescript_1.default.isTypeParameterDeclaration);
158
+ const variance = getVariance(declaration?.modifiers);
157
159
  const paramRefl = new models_1.TypeParameterReflection(param.symbol.name, parent, variance);
158
160
  const paramCtx = context.withScope(paramRefl);
159
161
  paramRefl.type = constraintT
@@ -162,6 +164,10 @@ function convertTypeParameters(context, parent, parameters) {
162
164
  paramRefl.default = defaultT
163
165
  ? context.converter.convertType(paramCtx, defaultT)
164
166
  : void 0;
167
+ // No way to determine this from the type parameter itself, need to go back to the declaration
168
+ if (declaration?.modifiers?.some((m) => m.kind === typescript_1.default.SyntaxKind.ConstKeyword)) {
169
+ paramRefl.flags.setFlag(models_1.ReflectionFlag.Const, true);
170
+ }
165
171
  context.registerReflection(paramRefl, param.getSymbol());
166
172
  context.trigger(converter_events_1.ConverterEvents.CREATE_TYPE_PARAMETER, paramRefl);
167
173
  return paramRefl;
@@ -180,9 +186,12 @@ function createTypeParamReflection(param, context) {
180
186
  paramRefl.default = param.default
181
187
  ? context.converter.convertType(paramScope, param.default)
182
188
  : void 0;
189
+ if (param.modifiers?.some((m) => m.kind === typescript_1.default.SyntaxKind.ConstKeyword)) {
190
+ paramRefl.flags.setFlag(models_1.ReflectionFlag.Const, true);
191
+ }
183
192
  context.registerReflection(paramRefl, param.symbol);
184
193
  if (typescript_1.default.isJSDocTemplateTag(param.parent)) {
185
- paramRefl.comment = (0, comments_1.getJsDocComment)(param.parent, context.converter.config, context.logger);
194
+ paramRefl.comment = (0, comments_1.getJsDocComment)(param.parent, context.converter.config, context.logger, context.checker);
186
195
  }
187
196
  context.trigger(converter_events_1.ConverterEvents.CREATE_TYPE_PARAMETER, paramRefl, param);
188
197
  return paramRefl;
@@ -29,7 +29,7 @@ function convertJsDocAlias(context, symbol, declaration, exportSymbol) {
29
29
  return;
30
30
  }
31
31
  const reflection = context.createDeclarationReflection(models_1.ReflectionKind.TypeAlias, symbol, exportSymbol);
32
- reflection.comment = (0, comments_1.getJsDocComment)(declaration, context.converter.config, context.logger);
32
+ reflection.comment = (0, comments_1.getJsDocComment)(declaration, context.converter.config, context.logger, context.checker);
33
33
  reflection.type = context.converter.convertType(context.withScope(reflection), declaration.typeExpression?.type);
34
34
  convertTemplateParameters(context.withScope(reflection), declaration.parent);
35
35
  context.finalizeDeclarationReflection(reflection);
@@ -37,7 +37,7 @@ function convertJsDocAlias(context, symbol, declaration, exportSymbol) {
37
37
  exports.convertJsDocAlias = convertJsDocAlias;
38
38
  function convertJsDocCallback(context, symbol, declaration, exportSymbol) {
39
39
  const alias = context.createDeclarationReflection(models_1.ReflectionKind.TypeAlias, symbol, exportSymbol);
40
- alias.comment = (0, comments_1.getJsDocComment)(declaration, context.converter.config, context.logger);
40
+ alias.comment = (0, comments_1.getJsDocComment)(declaration, context.converter.config, context.logger, context.checker);
41
41
  context.finalizeDeclarationReflection(alias);
42
42
  const ac = context.withScope(alias);
43
43
  alias.type = convertJsDocSignature(ac, declaration.typeExpression);
@@ -46,7 +46,7 @@ function convertJsDocCallback(context, symbol, declaration, exportSymbol) {
46
46
  exports.convertJsDocCallback = convertJsDocCallback;
47
47
  function convertJsDocInterface(context, declaration, symbol, exportSymbol) {
48
48
  const reflection = context.createDeclarationReflection(models_1.ReflectionKind.Interface, symbol, exportSymbol);
49
- reflection.comment = (0, comments_1.getJsDocComment)(declaration, context.converter.config, context.logger);
49
+ reflection.comment = (0, comments_1.getJsDocComment)(declaration, context.converter.config, context.logger, context.checker);
50
50
  context.finalizeDeclarationReflection(reflection);
51
51
  const rc = context.withScope(reflection);
52
52
  const type = context.checker.getDeclaredTypeOfSymbol(symbol);
@@ -66,7 +66,8 @@ let InheritDocPlugin = class InheritDocPlugin extends components_1.ConverterComp
66
66
  const index = reflection.parent
67
67
  .getAllSignatures()
68
68
  .indexOf(reflection);
69
- sourceRefl = sourceRefl.getAllSignatures()[index];
69
+ sourceRefl =
70
+ sourceRefl.getAllSignatures()[index] || sourceRefl;
70
71
  }
71
72
  }
72
73
  if (sourceRefl instanceof models_1.DeclarationReflection &&
@@ -242,8 +242,8 @@ function convertFunctionOrMethod(context, symbol, exportSymbol) {
242
242
  const scope = context.withScope(reflection);
243
243
  // Can't use zip here. We might have less declarations than signatures
244
244
  // or less signatures than declarations.
245
- for (let i = 0; i < signatures.length; i++) {
246
- (0, signature_1.createSignature)(scope, models_1.ReflectionKind.CallSignature, signatures[i], symbol, declarations[i]);
245
+ for (const sig of signatures) {
246
+ (0, signature_1.createSignature)(scope, models_1.ReflectionKind.CallSignature, sig, symbol);
247
247
  }
248
248
  }
249
249
  // getDeclaredTypeOfSymbol gets the INSTANCE type
@@ -353,8 +353,10 @@ function convertProperty(context, symbol, exportSymbol) {
353
353
  (typescript_1.default.isPropertyDeclaration(declaration) ||
354
354
  typescript_1.default.isPropertySignature(declaration) ||
355
355
  typescript_1.default.isParameter(declaration) ||
356
- typescript_1.default.isPropertyAccessExpression(declaration))) {
357
- if (!typescript_1.default.isPropertyAccessExpression(declaration)) {
356
+ typescript_1.default.isPropertyAccessExpression(declaration) ||
357
+ typescript_1.default.isPropertyAssignment(declaration))) {
358
+ if (!typescript_1.default.isPropertyAccessExpression(declaration) &&
359
+ !typescript_1.default.isPropertyAssignment(declaration)) {
358
360
  parameterType = declaration.type;
359
361
  }
360
362
  setModifiers(symbol, declaration, reflection);
@@ -543,7 +545,7 @@ function setModifiers(symbol, declaration, reflection) {
543
545
  reflection.setFlag(models_1.ReflectionFlag.Public);
544
546
  }
545
547
  reflection.setFlag(models_1.ReflectionFlag.Optional, (0, enum_1.hasAllFlags)(symbol.flags, typescript_1.default.SymbolFlags.Optional));
546
- reflection.setFlag(models_1.ReflectionFlag.Readonly, (0, enum_1.hasAllFlags)(symbol.checkFlags ?? 0, typescript_1.default.CheckFlags.Readonly) ||
548
+ reflection.setFlag(models_1.ReflectionFlag.Readonly, (0, enum_1.hasAllFlags)(typescript_1.default.getCheckFlags(symbol), typescript_1.default.CheckFlags.Readonly) ||
547
549
  (0, enum_1.hasAllFlags)(modifiers, typescript_1.default.ModifierFlags.Readonly));
548
550
  reflection.setFlag(models_1.ReflectionFlag.Abstract, (0, enum_1.hasAllFlags)(modifiers, typescript_1.default.ModifierFlags.Abstract));
549
551
  if (reflection.kindOf(models_1.ReflectionKind.Variable) &&
@@ -1,4 +1,4 @@
1
- import type { Reflection } from "../reflections";
1
+ import type { Reflection, ReflectionSymbolId } from "../reflections";
2
2
  import type { Serializer, Deserializer, JSONOutput } from "../../serialization";
3
3
  export type CommentDisplayPart = {
4
4
  kind: "text";
@@ -15,7 +15,7 @@ export interface InlineTagDisplayPart {
15
15
  kind: "inline-tag";
16
16
  tag: `@${string}`;
17
17
  text: string;
18
- target?: Reflection | string;
18
+ target?: Reflection | string | ReflectionSymbolId;
19
19
  }
20
20
  /**
21
21
  * A model that represents a single TypeDoc comment tag.
@@ -41,7 +41,7 @@ export declare class CommentTag {
41
41
  */
42
42
  constructor(tag: `@${string}`, text: CommentDisplayPart[]);
43
43
  clone(): CommentTag;
44
- toObject(): JSONOutput.CommentTag;
44
+ toObject(serializer: Serializer): JSONOutput.CommentTag;
45
45
  fromObject(de: Deserializer, obj: JSONOutput.CommentTag): void;
46
46
  }
47
47
  /**
@@ -75,11 +75,11 @@ export declare class Comment {
75
75
  kind: "inline-tag";
76
76
  tag: `@${string}`;
77
77
  text: string;
78
- target?: string | Reflection | undefined;
78
+ target?: string | Reflection | ReflectionSymbolId | undefined;
79
79
  })[];
80
- static serializeDisplayParts(parts: CommentDisplayPart[]): JSONOutput.CommentDisplayPart[];
80
+ static serializeDisplayParts(serializer: Serializer, parts: CommentDisplayPart[]): JSONOutput.CommentDisplayPart[];
81
81
  /** @hidden no point in showing this signature in api docs */
82
- static serializeDisplayParts(parts: CommentDisplayPart[] | undefined): JSONOutput.CommentDisplayPart[] | undefined;
82
+ static serializeDisplayParts(serializer: Serializer, parts: CommentDisplayPart[] | undefined): JSONOutput.CommentDisplayPart[] | undefined;
83
83
  static deserializeDisplayParts(de: Deserializer, parts: JSONOutput.CommentDisplayPart[]): CommentDisplayPart[];
84
84
  /**
85
85
  * The content of the comment which is not associated with a block tag.
@@ -22,11 +22,11 @@ class CommentTag {
22
22
  }
23
23
  return tag;
24
24
  }
25
- toObject() {
25
+ toObject(serializer) {
26
26
  return {
27
27
  tag: this.tag,
28
28
  name: this.name,
29
- content: Comment.serializeDisplayParts(this.content),
29
+ content: Comment.serializeDisplayParts(serializer, this.content),
30
30
  };
31
31
  }
32
32
  fromObject(de, obj) {
@@ -86,9 +86,15 @@ class Comment {
86
86
  case "@linkcode":
87
87
  case "@linkplain": {
88
88
  if (part.target) {
89
- const url = typeof part.target === "string"
90
- ? part.target
91
- : urlTo(part.target);
89
+ let url;
90
+ if (typeof part.target === "string") {
91
+ url = part.target;
92
+ }
93
+ else if (part.target && "id" in part.target) {
94
+ // No point in trying to resolve a ReflectionSymbolId at this point, we've already
95
+ // tried and failed during the resolution step.
96
+ url = urlTo(part.target);
97
+ }
92
98
  const text = part.tag === "@linkcode"
93
99
  ? `<code>${part.text}</code>`
94
100
  : part.text;
@@ -120,18 +126,28 @@ class Comment {
120
126
  static cloneDisplayParts(parts) {
121
127
  return parts.map((p) => ({ ...p }));
122
128
  }
123
- static serializeDisplayParts(parts) {
129
+ static serializeDisplayParts(serializer, parts) {
124
130
  return parts?.map((part) => {
125
131
  switch (part.kind) {
126
132
  case "text":
127
133
  case "code":
128
134
  return { ...part };
129
135
  case "inline-tag": {
136
+ let target;
137
+ if (typeof part.target === "string") {
138
+ target = part.target;
139
+ }
140
+ else if (part.target) {
141
+ if ("id" in part.target) {
142
+ target = part.target.id;
143
+ }
144
+ else {
145
+ target = part.target.toObject(serializer);
146
+ }
147
+ }
130
148
  return {
131
149
  ...part,
132
- target: typeof part.target === "object"
133
- ? part.target.id
134
- : part.target,
150
+ target,
135
151
  };
136
152
  }
137
153
  }
@@ -253,7 +269,7 @@ class Comment {
253
269
  }
254
270
  toObject(serializer) {
255
271
  return {
256
- summary: Comment.serializeDisplayParts(this.summary),
272
+ summary: Comment.serializeDisplayParts(serializer, this.summary),
257
273
  blockTags: serializer.toObjectsOptional(this.blockTags),
258
274
  modifierTags: this.modifierTags.size > 0
259
275
  ? Array.from(this.modifierTags)
@@ -170,7 +170,6 @@ class ReflectionFlags extends Array {
170
170
  }
171
171
  }
172
172
  }
173
- exports.ReflectionFlags = ReflectionFlags;
174
173
  ReflectionFlags.serializedFlags = [
175
174
  "isPrivate",
176
175
  "isProtected",
@@ -184,6 +183,7 @@ ReflectionFlags.serializedFlags = [
184
183
  "isConst",
185
184
  "isReadonly",
186
185
  ];
186
+ exports.ReflectionFlags = ReflectionFlags;
187
187
  var TraverseProperty;
188
188
  (function (TraverseProperty) {
189
189
  TraverseProperty[TraverseProperty["Children"] = 0] = "Children";
@@ -203,7 +203,7 @@ class ProjectReflection extends container_1.ContainerReflection {
203
203
  variant: this.variant,
204
204
  packageName: this.packageName,
205
205
  packageVersion: this.packageVersion,
206
- readme: comments_1.Comment.serializeDisplayParts(this.readme),
206
+ readme: comments_1.Comment.serializeDisplayParts(serializer, this.readme),
207
207
  symbolIdMap,
208
208
  };
209
209
  }
@@ -56,7 +56,6 @@ class RendererEvent extends events_1.Event {
56
56
  return event;
57
57
  }
58
58
  }
59
- exports.RendererEvent = RendererEvent;
60
59
  /**
61
60
  * Triggered before the renderer starts rendering a project.
62
61
  * @event
@@ -67,6 +66,7 @@ RendererEvent.BEGIN = "beginRender";
67
66
  * @event
68
67
  */
69
68
  RendererEvent.END = "endRender";
69
+ exports.RendererEvent = RendererEvent;
70
70
  /**
71
71
  * An event emitted by the {@link Renderer} class before and after the
72
72
  * markup of a page is rendered.
@@ -76,7 +76,6 @@ RendererEvent.END = "endRender";
76
76
  */
77
77
  class PageEvent extends events_1.Event {
78
78
  }
79
- exports.PageEvent = PageEvent;
80
79
  /**
81
80
  * Triggered before a document will be rendered.
82
81
  * @event
@@ -87,6 +86,7 @@ PageEvent.BEGIN = "beginPage";
87
86
  * @event
88
87
  */
89
88
  PageEvent.END = "endPage";
89
+ exports.PageEvent = PageEvent;
90
90
  /**
91
91
  * An event emitted when markdown is being parsed. Allows other plugins to manipulate the result.
92
92
  *
@@ -99,12 +99,12 @@ class MarkdownEvent extends events_1.Event {
99
99
  this.parsedText = parsedText;
100
100
  }
101
101
  }
102
- exports.MarkdownEvent = MarkdownEvent;
103
102
  /**
104
103
  * Triggered on the renderer when this plugin parses a markdown string.
105
104
  * @event
106
105
  */
107
106
  MarkdownEvent.PARSE = "parseMarkdown";
107
+ exports.MarkdownEvent = MarkdownEvent;
108
108
  /**
109
109
  * An event emitted when the search index is being prepared.
110
110
  */
@@ -136,9 +136,9 @@ class IndexEvent extends events_1.Event {
136
136
  this.searchFields = Array.from({ length: this.searchResults.length }, () => ({}));
137
137
  }
138
138
  }
139
- exports.IndexEvent = IndexEvent;
140
139
  /**
141
140
  * Triggered on the renderer when the search index is being prepared.
142
141
  * @event
143
142
  */
144
143
  IndexEvent.PREPARE_INDEX = "prepareIndex";
144
+ exports.IndexEvent = IndexEvent;
@@ -89,6 +89,12 @@ class DefaultTheme extends theme_1.Theme {
89
89
  project.url = "index.html";
90
90
  urls.push(new UrlMapping_1.UrlMapping("index.html", project, this.reflectionTemplate));
91
91
  }
92
+ else if (project.children?.every((child) => child.kindOf(models_1.ReflectionKind.Module))) {
93
+ // If there are no non-module children, then there's no point in having a modules page since there
94
+ // will be nothing on it besides the navigation, so redirect the module page to the readme page
95
+ project.url = "index.html";
96
+ urls.push(new UrlMapping_1.UrlMapping("index.html", project, this.indexTemplate));
97
+ }
92
98
  else {
93
99
  project.url = "modules.html";
94
100
  urls.push(new UrlMapping_1.UrlMapping("modules.html", project, this.reflectionTemplate));
@@ -182,8 +188,8 @@ class DefaultTheme extends theme_1.Theme {
182
188
  });
183
189
  }
184
190
  }
185
- exports.DefaultTheme = DefaultTheme;
186
191
  DefaultTheme.URL_PREFIX = /^(http|ftp)s?:\/\//;
192
+ exports.DefaultTheme = DefaultTheme;
187
193
  function hasReadme(readme) {
188
194
  return !readme.endsWith("none");
189
195
  }
@@ -8,6 +8,7 @@ function typeParameters(context, typeParameters) {
8
8
  utils_1.JSX.createElement("h4", null, "Type Parameters"),
9
9
  utils_1.JSX.createElement("ul", { class: "tsd-type-parameters" }, typeParameters?.map((item) => (utils_1.JSX.createElement("li", null,
10
10
  utils_1.JSX.createElement("h4", null,
11
+ item.flags.isConst && "const ",
11
12
  item.varianceModifier ? `${item.varianceModifier} ` : "",
12
13
  item.name,
13
14
  !!item.type && (utils_1.JSX.createElement(utils_1.JSX.Fragment, null,
@@ -6,8 +6,9 @@ const models_1 = require("../../../../models");
6
6
  const utils_1 = require("../../../../utils");
7
7
  function reflectionTemplate(context, props) {
8
8
  if ([models_1.ReflectionKind.TypeAlias, models_1.ReflectionKind.Variable].includes(props.model.kind) &&
9
- props.model instanceof models_1.DeclarationReflection)
9
+ props.model instanceof models_1.DeclarationReflection) {
10
10
  return context.memberDeclaration(props.model);
11
+ }
11
12
  return (utils_1.JSX.createElement(utils_1.JSX.Fragment, null,
12
13
  props.model.hasComment() && (utils_1.JSX.createElement("section", { class: "tsd-panel tsd-comment" }, context.comment(props.model))),
13
14
  (0, lib_1.hasTypeParameters)(props.model) && utils_1.JSX.createElement(utils_1.JSX.Fragment, null,
@@ -81,6 +81,7 @@ function renderTypeParametersSignature(typeParameters) {
81
81
  return (utils_1.JSX.createElement(utils_1.JSX.Fragment, null, !!typeParameters && typeParameters.length > 0 && (utils_1.JSX.createElement(utils_1.JSX.Fragment, null,
82
82
  utils_1.JSX.createElement("span", { class: "tsd-signature-symbol" }, "<"),
83
83
  join(utils_1.JSX.createElement("span", { class: "tsd-signature-symbol" }, ", "), typeParameters, (item) => (utils_1.JSX.createElement(utils_1.JSX.Fragment, null,
84
+ item.flags.isConst && "const ",
84
85
  item.varianceModifier ? `${item.varianceModifier} ` : "",
85
86
  utils_1.JSX.createElement("span", { class: "tsd-signature-type", "data-tsd-kind": models_1.ReflectionKind.singularString(item.kind) }, item.name)))),
86
87
  utils_1.JSX.createElement("span", { class: "tsd-signature-symbol" }, ">")))));
@@ -166,22 +166,23 @@ export interface Comment extends Partial<S<M.Comment, "blockTags" | "label">> {
166
166
  export interface CommentTag extends S<M.CommentTag, "tag" | "name"> {
167
167
  content: CommentDisplayPart[];
168
168
  }
169
- /**
170
- * If `target` is a number, it is a reflection ID. If a string, it is a URL.
171
- * `target` will only be set for `@link`, `@linkcode`, and `@linkplain` tags.
172
- */
173
169
  export type CommentDisplayPart = {
174
170
  kind: "text";
175
171
  text: string;
176
172
  } | {
177
173
  kind: "code";
178
174
  text: string;
179
- } | {
175
+ } | InlineTagDisplayPart;
176
+ /**
177
+ * If `target` is a number, it is a reflection ID. If a string, it is a URL.
178
+ * `target` will only be set for `@link`, `@linkcode`, and `@linkplain` tags.
179
+ */
180
+ export interface InlineTagDisplayPart {
180
181
  kind: "inline-tag";
181
182
  tag: `@${string}`;
182
183
  text: string;
183
- target?: string | number;
184
- };
184
+ target?: string | number | ReflectionSymbolId;
185
+ }
185
186
  export interface SourceReference extends S<M.SourceReference, "fileName" | "line" | "character" | "url"> {
186
187
  }
187
188
  export {};
@@ -41,7 +41,6 @@ class Serializer extends utils_1.EventDispatcher {
41
41
  return project;
42
42
  }
43
43
  }
44
- exports.Serializer = Serializer;
45
44
  /**
46
45
  * Triggered when the {@link Serializer} begins transforming a project.
47
46
  * @event EVENT_BEGIN
@@ -52,3 +51,4 @@ Serializer.EVENT_BEGIN = "begin";
52
51
  * @event EVENT_END
53
52
  */
54
53
  Serializer.EVENT_END = "end";
54
+ exports.Serializer = Serializer;
@@ -49,9 +49,9 @@ class ComponentEvent extends events_1.Event {
49
49
  this.component = component;
50
50
  }
51
51
  }
52
- exports.ComponentEvent = ComponentEvent;
53
52
  ComponentEvent.ADDED = "componentAdded";
54
53
  ComponentEvent.REMOVED = "componentRemoved";
54
+ exports.ComponentEvent = ComponentEvent;
55
55
  /**
56
56
  * Component base class. Has an owner (unless it's the application root component),
57
57
  * can dispatch events to its children, and has access to the root Application component.
@@ -311,9 +311,9 @@ function getEntryPointsForLegacyPackages(logger, packageGlobPaths, options) {
311
311
  logger.error(`Entry point "${packageEntryPoint}" does not appear to be built by/included in the tsconfig found at "${tsconfigFile}"`);
312
312
  return;
313
313
  }
314
+ const packageName = packageJson["name"];
314
315
  results.push({
315
- displayName: typedocPackageConfig?.displayName ??
316
- packageJson["name"],
316
+ displayName: typedocPackageConfig?.displayName ?? packageName,
317
317
  version: includeVersion
318
318
  ? packageJson["version"]
319
319
  : void 0,
@@ -99,6 +99,7 @@ export interface TypeDocOptionMap {
99
99
  navigationLinks: ManuallyValidatedOption<Record<string, string>>;
100
100
  sidebarLinks: ManuallyValidatedOption<Record<string, string>>;
101
101
  commentStyle: typeof CommentStyle;
102
+ useTsLinkResolution: boolean;
102
103
  blockTags: `@${string}`[];
103
104
  inlineTags: `@${string}`[];
104
105
  modifierTags: `@${string}`[];
@@ -125,6 +126,7 @@ export interface TypeDocOptionMap {
125
126
  plugin: string[];
126
127
  logLevel: typeof LogLevel;
127
128
  treatWarningsAsErrors: boolean;
129
+ treatValidationWarningsAsErrors: boolean;
128
130
  intentionallyNotExported: string[];
129
131
  validation: ValidationOptions;
130
132
  requiredToBeDocumented: ReflectionKind.KindString[];
@@ -291,7 +291,13 @@ function addTypeDocOptions(options) {
291
291
  name: "excludeTags",
292
292
  help: "Remove the listed block/modifier tags from doc comments.",
293
293
  type: declaration_1.ParameterType.Array,
294
- defaultValue: ["@override", "@virtual", "@privateRemarks"],
294
+ defaultValue: [
295
+ "@override",
296
+ "@virtual",
297
+ "@privateRemarks",
298
+ "@satisfies",
299
+ "@overload",
300
+ ],
295
301
  validate(value) {
296
302
  if (!Validation.validate([Array, Validation.isTagString], value)) {
297
303
  throw new Error(`excludeTags must be an array of valid tag names.`);
@@ -395,6 +401,12 @@ function addTypeDocOptions(options) {
395
401
  map: declaration_1.CommentStyle,
396
402
  defaultValue: declaration_1.CommentStyle.JSDoc,
397
403
  });
404
+ options.addDeclaration({
405
+ name: "useTsLinkResolution",
406
+ help: "Use TypeScript's link resolution when determining where @link tags point. This only applies to JSDoc style comments.",
407
+ type: declaration_1.ParameterType.Boolean,
408
+ defaultValue: true,
409
+ });
398
410
  options.addDeclaration({
399
411
  name: "blockTags",
400
412
  help: "Block tags which TypeDoc should recognize when parsing comments.",
@@ -582,7 +594,12 @@ function addTypeDocOptions(options) {
582
594
  });
583
595
  options.addDeclaration({
584
596
  name: "treatWarningsAsErrors",
585
- help: "If set, warnings will be treated as errors.",
597
+ help: "If set, all warnings will be treated as errors.",
598
+ type: declaration_1.ParameterType.Boolean,
599
+ });
600
+ options.addDeclaration({
601
+ name: "treatValidationWarningsAsErrors",
602
+ help: "If set, warnings emitted during validation will be treated as errors. This option cannot be used to disable treatWarningsAsErrors for validation warnings.",
586
603
  type: declaration_1.ParameterType.Boolean,
587
604
  });
588
605
  options.addDeclaration({
@@ -1,6 +1,6 @@
1
1
  export declare const tsdocBlockTags: readonly ["@deprecated", "@param", "@remarks", "@returns", "@throws", "@privateRemarks", "@defaultValue", "@typeParam"];
2
- export declare const blockTags: readonly ["@deprecated", "@param", "@remarks", "@returns", "@throws", "@privateRemarks", "@defaultValue", "@typeParam", "@module", "@inheritDoc", "@group", "@category", "@template", "@type", "@typedef", "@callback", "@prop", "@property"];
2
+ export declare const blockTags: readonly ["@deprecated", "@param", "@remarks", "@returns", "@throws", "@privateRemarks", "@defaultValue", "@typeParam", "@module", "@inheritDoc", "@group", "@category", "@template", "@type", "@typedef", "@callback", "@prop", "@property", "@satisfies"];
3
3
  export declare const tsdocInlineTags: readonly ["@link", "@inheritDoc", "@label"];
4
4
  export declare const inlineTags: string[];
5
5
  export declare const tsdocModifierTags: readonly ["@public", "@private", "@protected", "@internal", "@readonly", "@packageDocumentation", "@eventProperty", "@alpha", "@beta", "@experimental", "@sealed", "@override", "@virtual"];
6
- export declare const modifierTags: readonly ["@public", "@private", "@protected", "@internal", "@readonly", "@packageDocumentation", "@eventProperty", "@alpha", "@beta", "@experimental", "@sealed", "@override", "@virtual", "@hidden", "@ignore", "@enum", "@event"];
6
+ export declare const modifierTags: readonly ["@public", "@private", "@protected", "@internal", "@readonly", "@packageDocumentation", "@eventProperty", "@alpha", "@beta", "@experimental", "@sealed", "@override", "@virtual", "@hidden", "@ignore", "@enum", "@event", "@overload"];
@@ -26,6 +26,7 @@ exports.blockTags = [
26
26
  "@callback",
27
27
  "@prop",
28
28
  "@property",
29
+ "@satisfies",
29
30
  ];
30
31
  exports.tsdocInlineTags = ["@link", "@inheritDoc", "@label"];
31
32
  exports.inlineTags = [...exports.tsdocInlineTags, "@linkcode", "@linkplain"];
@@ -50,4 +51,5 @@ exports.modifierTags = [
50
51
  "@ignore",
51
52
  "@enum",
52
53
  "@event",
54
+ "@overload",
53
55
  ];
@@ -44,13 +44,13 @@ function extractTypedocConfigFromPackageManifest(logger, packageJsonPath) {
44
44
  return undefined;
45
45
  }
46
46
  if (hasOwnProperty(packageJson, "typedoc") &&
47
- typeof packageJson.typedoc == "object" &&
48
- packageJson.typedoc) {
49
- if (!(0, validation_1.validate)(typedocPackageManifestConfigSchema, packageJson.typedoc)) {
47
+ typeof packageJson["typedoc"] == "object" &&
48
+ packageJson["typedoc"]) {
49
+ if (!(0, validation_1.validate)(typedocPackageManifestConfigSchema, packageJson["typedoc"])) {
50
50
  logger.error(`Typedoc config extracted from package manifest file ${packageJsonPath} is not valid`);
51
51
  return undefined;
52
52
  }
53
- return packageJson.typedoc;
53
+ return packageJson["typedoc"];
54
54
  }
55
55
  return undefined;
56
56
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "typedoc",
3
3
  "description": "Create api documentation for TypeScript projects.",
4
- "version": "0.24.0-beta.3",
4
+ "version": "0.24.0-beta.4",
5
5
  "homepage": "https://typedoc.org",
6
6
  "exports": {
7
7
  ".": "./dist/index.js",
@@ -30,24 +30,24 @@
30
30
  "shiki": "^0.14.1"
31
31
  },
32
32
  "peerDependencies": {
33
- "typescript": "4.6.x || 4.7.x || 4.8.x || 4.9.x"
33
+ "typescript": "4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x"
34
34
  },
35
35
  "devDependencies": {
36
36
  "@types/lunr": "^2.3.4",
37
37
  "@types/marked": "^4.0.8",
38
38
  "@types/mocha": "^10.0.1",
39
39
  "@types/node": "14",
40
- "@typescript-eslint/eslint-plugin": "^5.51.0",
41
- "@typescript-eslint/parser": "^5.51.0",
40
+ "@typescript-eslint/eslint-plugin": "^5.55.0",
41
+ "@typescript-eslint/parser": "^5.55.0",
42
42
  "@typestrong/fs-fixture-builder": "github:TypeStrong/fs-fixture-builder#8abd1494280116ff5318dde2c50ad01e1663790c",
43
- "c8": "^7.12.0",
44
- "esbuild": "^0.17.7",
45
- "eslint": "^8.34.0",
43
+ "c8": "^7.13.0",
44
+ "esbuild": "^0.17.12",
45
+ "eslint": "^8.36.0",
46
46
  "mocha": "^10.2.0",
47
47
  "prettier": "2.8.4",
48
48
  "puppeteer": "^13.5.2",
49
49
  "ts-node": "^10.9.1",
50
- "typescript": "4.9.5"
50
+ "typescript": "5.0.2"
51
51
  },
52
52
  "files": [
53
53
  "/bin",
package/static/style.css CHANGED
@@ -483,10 +483,9 @@ blockquote {
483
483
  .has-menu .col-menu {
484
484
  visibility: visible;
485
485
  transform: translate(0, 0);
486
- display: grid;
487
- align-items: center;
488
- grid-template-rows: auto 1fr;
489
- grid-gap: 1.5rem;
486
+ display: flex;
487
+ flex-direction: column;
488
+ gap: 1.5rem;
490
489
  max-height: 100vh;
491
490
  padding: 1rem 2rem;
492
491
  }
@@ -911,7 +910,7 @@ a.tsd-index-link {
911
910
  margin-right: 0.8rem;
912
911
  }
913
912
 
914
- @media (min-width: 1024px) {
913
+ @media (min-width: 1025px) {
915
914
  .col-content {
916
915
  margin: 2rem auto;
917
916
  }
package/tsdoc.json CHANGED
@@ -66,6 +66,22 @@
66
66
  "tagName": "@linkplain",
67
67
  "syntaxKind": "block",
68
68
  "allowMultiple": true
69
+ },
70
+ {
71
+ "tagName": "@private",
72
+ "syntaxKind": "modifier"
73
+ },
74
+ {
75
+ "tagName": "@protected",
76
+ "syntaxKind": "modifier"
77
+ },
78
+ {
79
+ "tagName": "@satisfies",
80
+ "syntaxKind": "block"
81
+ },
82
+ {
83
+ "tagName": "@overload",
84
+ "syntaxKind": "modifier"
69
85
  }
70
86
  ]
71
87
  }