typedoc 0.28.15 → 0.28.16

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.
@@ -2,7 +2,7 @@ import ts from "typescript";
2
2
  import { Comment, ReflectionKind } from "../../models/index.js";
3
3
  import type { CommentStyle, JsDocCompatibility, ValidationOptions } from "../../utils/options/declaration.js";
4
4
  import type { FileRegistry } from "../../models/FileRegistry.js";
5
- import { type Logger } from "#utils";
5
+ import { Logger } from "#utils";
6
6
  import type { Context } from "../context.js";
7
7
  export interface CommentParserConfig {
8
8
  blockTags: Set<string>;
@@ -4,7 +4,7 @@ import { lexBlockComment } from "./blockLexer.js";
4
4
  import { discoverComment, discoverFileComments, discoverNodeComment, discoverSignatureComment, } from "./discovery.js";
5
5
  import { lexLineComments } from "./lineLexer.js";
6
6
  import { parseComment } from "./parser.js";
7
- import { assertNever, i18n } from "#utils";
7
+ import { assertNever, i18n, Logger, setUnion } from "#utils";
8
8
  const jsDocCommentKinds = [
9
9
  ts.SyntaxKind.JSDocPropertyTag,
10
10
  ts.SyntaxKind.JSDocCallbackTag,
@@ -21,16 +21,10 @@ export function clearCommentCache() {
21
21
  commentCache = new WeakMap();
22
22
  commentDiscoveryId = 0;
23
23
  }
24
- function getCommentWithCache(discovered, context) {
24
+ function getCommentIgnoringCacheNoDiscoveryId(discovered, context) {
25
25
  if (!discovered)
26
26
  return;
27
27
  const { file, ranges, jsDoc } = discovered;
28
- const cache = commentCache.get(file) || new Map();
29
- if (cache.has(ranges[0].pos)) {
30
- const clone = cache.get(ranges[0].pos).clone();
31
- clone.inheritedFromParentDeclaration = discovered.inheritedFromParentDeclaration;
32
- return clone;
33
- }
34
28
  let comment;
35
29
  switch (ranges[0].kind) {
36
30
  case ts.SyntaxKind.MultiLineCommentTrivia:
@@ -42,8 +36,23 @@ function getCommentWithCache(discovered, context) {
42
36
  default:
43
37
  assertNever(ranges[0].kind);
44
38
  }
45
- comment.discoveryId = ++commentDiscoveryId;
46
39
  comment.inheritedFromParentDeclaration = discovered.inheritedFromParentDeclaration;
40
+ return comment;
41
+ }
42
+ function getCommentWithCache(discovered, context) {
43
+ if (!discovered)
44
+ return;
45
+ const { file, ranges } = discovered;
46
+ const cache = commentCache.get(file) || new Map();
47
+ if (cache.has(ranges[0].pos)) {
48
+ const clone = cache.get(ranges[0].pos).clone();
49
+ clone.inheritedFromParentDeclaration = discovered.inheritedFromParentDeclaration;
50
+ return clone;
51
+ }
52
+ const comment = getCommentIgnoringCacheNoDiscoveryId(discovered, context);
53
+ if (!comment)
54
+ return;
55
+ comment.discoveryId = ++commentDiscoveryId;
47
56
  cache.set(ranges[0].pos, comment);
48
57
  commentCache.set(file, cache);
49
58
  return comment.clone();
@@ -99,14 +108,24 @@ export function getNodeComment(node, moduleComment, context) {
99
108
  return getCommentImpl(discoverNodeComment(node, context.config.commentStyle), moduleComment, context);
100
109
  }
101
110
  export function getFileComment(file, context) {
111
+ const quietContext = {
112
+ ...context,
113
+ logger: new Logger(),
114
+ };
102
115
  for (const commentSource of discoverFileComments(file, context.config.commentStyle)) {
103
- const comment = getCommentWithCache(commentSource, context);
116
+ // First parse the comment without adding the parse to the cache
117
+ // and without logging any messages. If we end up not using this as
118
+ // a file comment we want to avoid parsing it with warnings here as
119
+ // it might be associated with a JSDoc parse which has special
120
+ // handling to allow modifier tags to be specified as {@mod}
121
+ // and if it gets added to the cache here we'll get unwanted warnings
122
+ const comment = getCommentIgnoringCacheNoDiscoveryId(commentSource, quietContext);
104
123
  if (comment?.getTag("@license") || comment?.getTag("@import")) {
105
124
  continue;
106
125
  }
107
126
  if (comment?.getTag("@module") ||
108
127
  comment?.hasModifier("@packageDocumentation")) {
109
- return comment;
128
+ return getCommentWithCache(commentSource, context);
110
129
  }
111
130
  return;
112
131
  }
@@ -127,6 +146,33 @@ function getConstructorParamPropertyComment(symbol, context) {
127
146
  export function getSignatureComment(declaration, context) {
128
147
  return getCommentImpl(discoverSignatureComment(declaration, context.checker, context.config.commentStyle), false, context);
129
148
  }
149
+ function buildJsDocCommentFromParts(declaration, parts, sourceComment, context) {
150
+ if (!parts) {
151
+ return undefined;
152
+ }
153
+ const comment = new Comment(Comment.cloneDisplayParts(parts));
154
+ comment.sourcePath = sourceComment.sourcePath;
155
+ for (let i = 0; i < comment.summary.length;) {
156
+ const part = comment.summary[i];
157
+ if (part.kind === "inline-tag" &&
158
+ !part.text.trim() &&
159
+ context.config.modifierTags.has(part.tag)) {
160
+ comment.modifierTags.add(part.tag);
161
+ comment.summary.splice(i, 1);
162
+ }
163
+ else if (part.kind === "inline-tag" &&
164
+ part.text.trim() &&
165
+ context.config.modifierTags.has(part.tag) &&
166
+ !context.config.inlineTags.has(part.tag)) {
167
+ context.logger.warn(i18n.inline_tag_0_not_parsed_as_modifier_tag_1(part.tag, part.text.trim()), declaration);
168
+ ++i;
169
+ }
170
+ else {
171
+ ++i;
172
+ }
173
+ }
174
+ return comment;
175
+ }
130
176
  export function getJsDocComment(declaration, context) {
131
177
  const file = declaration.getSourceFile();
132
178
  // First, get the whole comment. We know we'll need all of it.
@@ -134,6 +180,15 @@ export function getJsDocComment(declaration, context) {
134
180
  while (!ts.isJSDoc(parent)) {
135
181
  parent = parent.parent;
136
182
  }
183
+ // Build a custom context to allow modifier tags to be written as inline
184
+ // tags as otherwise there's no way to specify them here #2916 #3050
185
+ const contextWithInline = {
186
+ ...context,
187
+ config: {
188
+ ...context.config,
189
+ inlineTags: setUnion(context.config.inlineTags, context.config.modifierTags),
190
+ },
191
+ };
137
192
  // Then parse it.
138
193
  const comment = getCommentWithCache({
139
194
  file,
@@ -146,12 +201,10 @@ export function getJsDocComment(declaration, context) {
146
201
  ],
147
202
  jsDoc: parent,
148
203
  inheritedFromParentDeclaration: false,
149
- }, context);
204
+ }, contextWithInline);
150
205
  // And pull out the tag we actually care about.
151
206
  if (ts.isJSDocEnumTag(declaration)) {
152
- const result = new Comment(comment.getTag("@enum")?.content);
153
- result.sourcePath = comment.sourcePath;
154
- return result;
207
+ return buildJsDocCommentFromParts(declaration, comment.getTag("@enum")?.content, comment, context);
155
208
  }
156
209
  if (ts.isJSDocTemplateTag(declaration) &&
157
210
  declaration.comment &&
@@ -183,8 +236,6 @@ export function getJsDocComment(declaration, context) {
183
236
  }
184
237
  }
185
238
  else {
186
- const result = new Comment(Comment.cloneDisplayParts(tag.content));
187
- result.sourcePath = comment.sourcePath;
188
- return result;
239
+ return buildJsDocCommentFromParts(declaration, tag.content, comment, context);
189
240
  }
190
241
  }
@@ -1,6 +1,7 @@
1
1
  import ts from "typescript";
2
2
  import { ParameterReflection, type Reflection, ReflectionKind, SignatureReflection, TypeParameterReflection } from "../../models/index.js";
3
3
  import type { Context } from "../context.js";
4
+ export declare function convertConstructSignatures(context: Context, symbol: ts.Symbol): void;
4
5
  export declare function createSignature(context: Context, kind: ReflectionKind.CallSignature | ReflectionKind.ConstructorSignature | ReflectionKind.GetSignature | ReflectionKind.SetSignature, signature: ts.Signature, symbol: ts.Symbol | undefined, declaration?: ts.SignatureDeclaration | ts.JSDocSignature): void;
5
6
  /**
6
7
  * Special cased constructor factory for functions tagged with `@class`
@@ -4,6 +4,19 @@ 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
+ export function convertConstructSignatures(context, symbol) {
8
+ const type = context.checker.getDeclaredTypeOfSymbol(symbol);
9
+ // These get added as a "constructor" member of this interface. This is a problem... but nobody
10
+ // has complained yet. We really ought to have a constructSignatures property on the reflection instead.
11
+ const constructSignatures = context.checker.getSignaturesOfType(type, ts.SignatureKind.Construct);
12
+ if (constructSignatures.length) {
13
+ const constructMember = new DeclarationReflection("constructor", ReflectionKind.Constructor, context.scope);
14
+ context.postReflectionCreation(constructMember, symbol, void 0);
15
+ context.finalizeDeclarationReflection(constructMember);
16
+ const constructContext = context.withScope(constructMember);
17
+ constructSignatures.forEach((sig) => createSignature(constructContext, ReflectionKind.ConstructorSignature, sig, symbol));
18
+ }
19
+ }
7
20
  export function createSignature(context, kind, signature, symbol, declaration) {
8
21
  assert(context.scope instanceof DeclarationReflection);
9
22
  declaration ||= signature.getDeclaration();
@@ -1,4 +1,4 @@
1
1
  import ts from "typescript";
2
2
  import type { Context } from "./context.js";
3
- export declare function convertJsDocAlias(context: Context, symbol: ts.Symbol, declaration: ts.JSDocTypedefTag | ts.JSDocEnumTag, exportSymbol?: ts.Symbol): void;
3
+ export declare function convertJsDocAlias(context: Context, symbol: ts.Symbol, declaration: ts.JSDocTypedefTag | ts.JSDocEnumTag, exportSymbol?: ts.Symbol): undefined;
4
4
  export declare function convertJsDocCallback(context: Context, symbol: ts.Symbol, declaration: ts.JSDocCallbackTag, exportSymbol?: ts.Symbol): void;
@@ -5,13 +5,44 @@ import { ok } from "assert";
5
5
  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
- import { convertParameterNodes, convertTemplateParameterNodes } from "./factories/signature.js";
8
+ import { convertConstructSignatures, convertParameterNodes, convertTemplateParameterNodes, createSignature, } from "./factories/signature.js";
9
+ import { i18n } from "#utils";
10
+ import { convertIndexSignatures } from "./factories/index-signature.js";
11
+ // This is almost convertTypeAliasAsInterface, but unfortunately needs to be separate
12
+ // due to type parameters being different in JSDoc comments
13
+ function convertJsDocAliasAsInterface(context, symbol, exportSymbol, declaration) {
14
+ const reflection = context.createDeclarationReflection(ReflectionKind.Interface, symbol, exportSymbol);
15
+ context.finalizeDeclarationReflection(reflection);
16
+ const rc = context.withScope(reflection);
17
+ const type = context.checker.getTypeAtLocation(declaration);
18
+ if (type.getFlags() & ts.TypeFlags.Union) {
19
+ context.logger.warn(i18n.converting_union_as_interface(), declaration);
20
+ }
21
+ // Interfaces have properties
22
+ for (const prop of type.getProperties()) {
23
+ context.converter.convertSymbol(rc, prop);
24
+ }
25
+ // And type parameters
26
+ convertTemplateParameters(rc, declaration.parent);
27
+ // And maybe call signatures
28
+ context.checker
29
+ .getSignaturesOfType(type, ts.SignatureKind.Call)
30
+ .forEach((sig) => createSignature(rc, ReflectionKind.CallSignature, sig, symbol));
31
+ // And maybe constructor signatures
32
+ convertConstructSignatures(rc, symbol);
33
+ // And finally, index signatures
34
+ convertIndexSignatures(rc, type);
35
+ }
9
36
  export function convertJsDocAlias(context, symbol, declaration, exportSymbol) {
10
37
  if (declaration.typeExpression &&
11
38
  ts.isJSDocTypeLiteral(declaration.typeExpression)) {
12
39
  convertJsDocInterface(context, declaration, symbol, exportSymbol);
13
40
  return;
14
41
  }
42
+ const comment = context.getJsDocComment(declaration);
43
+ if (comment?.hasModifier("@interface")) {
44
+ return convertJsDocAliasAsInterface(context, symbol, exportSymbol, declaration);
45
+ }
15
46
  // If the typedef tag is just referring to another type-space symbol, with no type parameters
16
47
  // or appropriate forwarding type parameters, then we treat it as a re-export instead of creating
17
48
  // a type alias with an import type.
@@ -21,7 +52,7 @@ export function convertJsDocAlias(context, symbol, declaration, exportSymbol) {
21
52
  return;
22
53
  }
23
54
  const reflection = context.createDeclarationReflection(ReflectionKind.TypeAlias, symbol, exportSymbol);
24
- reflection.comment = context.getJsDocComment(declaration);
55
+ reflection.comment = comment;
25
56
  reflection.type = context.converter.convertType(context.withScope(reflection), declaration.typeExpression?.type);
26
57
  convertTemplateParameters(context.withScope(reflection), declaration.parent);
27
58
  context.finalizeDeclarationReflection(reflection);
@@ -14,6 +14,7 @@ export declare class ImplementsPlugin extends ConverterComponent {
14
14
  */
15
15
  private analyzeImplements;
16
16
  private analyzeInheritance;
17
+ private cleanUpImplements;
17
18
  private onResolveEnd;
18
19
  private onRevive;
19
20
  private resolve;
@@ -95,10 +95,6 @@ export class ImplementsPlugin extends ConverterComponent {
95
95
  // serialization/deserialization, might point to an unexpected location. (See the mixin
96
96
  // converter tests, I suspect this might actually be an indication of something else slightly
97
97
  // broken there, but don't want to spend more time with this right now.)
98
- // #2982/#3007, even more unfortunately, we only want to keep the link if it is pointing
99
- // to a reflection which will receive a link during rendering, we pick this based on it being
100
- // the type of member we expect to point to.
101
- const isValidRef = (ref) => !!ref.reflection?.parent?.kindOf(ReflectionKind.ClassOrInterface | ReflectionKind.Method | ReflectionKind.Constructor);
102
98
  for (const child of reflection.children || []) {
103
99
  if (child.inheritedFrom && !isValidRef(child.inheritedFrom)) {
104
100
  child.inheritedFrom = ReferenceType.createBrokenReference(child.inheritedFrom.name, project, child.inheritedFrom.package);
@@ -116,6 +112,19 @@ export class ImplementsPlugin extends ConverterComponent {
116
112
  }
117
113
  }
118
114
  }
115
+ cleanUpImplements(project, reflection) {
116
+ // #3052, the same problem as #2978 applies for implements
117
+ for (const child of reflection.children || []) {
118
+ if (child.implementationOf && !isValidRef(child.implementationOf)) {
119
+ child.implementationOf = ReferenceType.createBrokenReference(child.implementationOf.name, project, child.implementationOf.package);
120
+ }
121
+ for (const childSig of child.getAllSignatures()) {
122
+ if (childSig.implementationOf && !isValidRef(childSig.implementationOf)) {
123
+ childSig.implementationOf = ReferenceType.createBrokenReference(childSig.implementationOf.name, project, childSig.implementationOf.package);
124
+ }
125
+ }
126
+ }
127
+ }
119
128
  onResolveEnd(context) {
120
129
  this.resolve(context.project);
121
130
  }
@@ -184,6 +193,10 @@ export class ImplementsPlugin extends ConverterComponent {
184
193
  reflection.extendedTypes) {
185
194
  this.analyzeInheritance(project, reflection);
186
195
  }
196
+ if (reflection.kindOf(ReflectionKind.ClassOrInterface) &&
197
+ (reflection.extendedTypes || reflection.implementedTypes)) {
198
+ this.cleanUpImplements(project, reflection);
199
+ }
187
200
  }
188
201
  getExtensionInfo(context, reflection) {
189
202
  if (!reflection || !reflection.kindOf(ReflectionKind.Inheritable)) {
@@ -417,3 +430,9 @@ function findMatchingMember(toMatch, container) {
417
430
  return container.children?.find((child) => child.name == toMatch.name &&
418
431
  child.flags.isStatic === toMatch.flags.isStatic);
419
432
  }
433
+ // #2982/#3007 unfortunately, we only want to keep the link if it is pointing
434
+ // to a reflection which will receive a link during rendering, we pick this based on it being
435
+ // the type of member we expect to point to.
436
+ function isValidRef(ref) {
437
+ return !!ref.reflection?.parent?.kindOf(ReflectionKind.ClassOrInterface | ReflectionKind.Method | ReflectionKind.Constructor);
438
+ }
@@ -246,5 +246,9 @@ regionTagREsByExt["php"] = regionTagREsByExt["cs"];
246
246
  regionTagREsByExt["ps1"] = regionTagREsByExt["cs"];
247
247
  regionTagREsByExt["py"] = regionTagREsByExt["cs"];
248
248
  regionTagREsByExt["js"] = regionTagREsByExt["ts"];
249
+ regionTagREsByExt["mjs"] = regionTagREsByExt["ts"];
249
250
  regionTagREsByExt["mts"] = regionTagREsByExt["ts"];
251
+ regionTagREsByExt["cjs"] = regionTagREsByExt["ts"];
250
252
  regionTagREsByExt["cts"] = regionTagREsByExt["ts"];
253
+ regionTagREsByExt["jsx"] = regionTagREsByExt["ts"];
254
+ regionTagREsByExt["tsx"] = regionTagREsByExt["ts"];
@@ -33,7 +33,7 @@ var __runInitializers = (this && this.__runInitializers) || function (thisArg, i
33
33
  return useValue ? value : void 0;
34
34
  };
35
35
  import ts from "typescript";
36
- import { DeclarationReflection, SignatureReflection } from "../../models/index.js";
36
+ import { DeclarationReflection, ReflectionKind, SignatureReflection } from "../../models/index.js";
37
37
  import { ConverterComponent } from "../components.js";
38
38
  import { getCommonDirectory, normalizePath, Option } from "../../utils/index.js";
39
39
  import { isNamedNode } from "../utils/nodes.js";
@@ -120,7 +120,7 @@ let SourcePlugin = (() => {
120
120
  * @param reflection The reflection that is currently processed.
121
121
  */
122
122
  onDeclaration(context, reflection) {
123
- if (this.disableSources)
123
+ if (this.disableSources || reflection.kindOf(ReflectionKind.TypeLiteral))
124
124
  return;
125
125
  const symbol = context.getSymbolFromReflection(reflection);
126
126
  for (const node of symbol?.declarations || []) {
@@ -139,7 +139,7 @@ let SourcePlugin = (() => {
139
139
  }
140
140
  }
141
141
  onSignature(_context, reflection, sig) {
142
- if (this.disableSources || !sig)
142
+ if (this.disableSources || !sig || reflection.parent.kindOf(ReflectionKind.TypeLiteral))
143
143
  return;
144
144
  const sourceFile = sig.getSourceFile();
145
145
  const fileName = normalizePath(sourceFile.fileName);
@@ -4,7 +4,7 @@ import { DeclarationReflection, IntrinsicType, LiteralType, ReferenceReflection,
4
4
  import { getEnumFlags, hasAllFlags, hasAnyFlag, i18n, removeFlag } from "#utils";
5
5
  import { convertDefaultValue } from "./convert-expression.js";
6
6
  import { convertIndexSignatures } from "./factories/index-signature.js";
7
- import { convertTypeParameters, createConstructSignatureWithType, createSignature, createTypeParamReflection, } from "./factories/signature.js";
7
+ import { convertConstructSignatures, convertTypeParameters, createConstructSignatureWithType, createSignature, createTypeParamReflection, } from "./factories/signature.js";
8
8
  import { convertJsDocAlias, convertJsDocCallback } from "./jsdoc.js";
9
9
  import { getHeritageTypes } from "./utils/nodes.js";
10
10
  import { removeUndefined } from "./utils/reflections.js";
@@ -522,19 +522,6 @@ function convertConstructor(context, symbol) {
522
522
  createSignature(reflectionContext, ReflectionKind.ConstructorSignature, sig, symbol);
523
523
  }
524
524
  }
525
- function convertConstructSignatures(context, symbol) {
526
- const type = context.checker.getDeclaredTypeOfSymbol(symbol);
527
- // These get added as a "constructor" member of this interface. This is a problem... but nobody
528
- // has complained yet. We really ought to have a constructSignatures property on the reflection instead.
529
- const constructSignatures = context.checker.getSignaturesOfType(type, ts.SignatureKind.Construct);
530
- if (constructSignatures.length) {
531
- const constructMember = new DeclarationReflection("constructor", ReflectionKind.Constructor, context.scope);
532
- context.postReflectionCreation(constructMember, symbol, void 0);
533
- context.finalizeDeclarationReflection(constructMember);
534
- const constructContext = context.withScope(constructMember);
535
- constructSignatures.forEach((sig) => createSignature(constructContext, ReflectionKind.ConstructorSignature, sig, symbol));
536
- }
537
- }
538
525
  function convertAlias(context, symbol, exportSymbol) {
539
526
  // If this is a namespace marked as a primary export or directly within one
540
527
  // marked as a primary export then we should convert it immediately rather than deferring
@@ -37,6 +37,7 @@ module.exports = {
37
37
  comments_for_0_are_declared_at_1: `The comments for {0} are declared at:\n\t{1}`,
38
38
  // comments/parser.ts
39
39
  multiple_type_parameters_on_template_tag_unsupported: `TypeDoc does not support multiple type parameters defined in a single @template tag with a comment`,
40
+ inline_tag_0_not_parsed_as_modifier_tag_1: `The inline tag {0} was likely intended to be a modifier tag but was not parsed as one due to including content "{1}"`,
40
41
  failed_to_find_jsdoc_tag_for_name_0: `Failed to find JSDoc tag for {0} after parsing comment, please file a bug report`,
41
42
  relative_path_0_is_not_a_file_and_will_not_be_copied_to_output: `The relative path {0} is not a file and will not be copied to the output directory`,
42
43
  inline_inheritdoc_should_not_appear_in_block_tag_in_comment_at_0: "An inline @inheritDoc tag should not appear within a block tag as it will not be processed in comment at {0}",
@@ -33,6 +33,7 @@ declare const _default: {
33
33
  readonly symbol_0_has_multiple_declarations_with_comment: "{0} has multiple declarations with a comment. An arbitrary comment will be used";
34
34
  readonly comments_for_0_are_declared_at_1: "The comments for {0} are declared at:\n\t{1}";
35
35
  readonly multiple_type_parameters_on_template_tag_unsupported: "TypeDoc does not support multiple type parameters defined in a single @template tag with a comment";
36
+ readonly inline_tag_0_not_parsed_as_modifier_tag_1: "The inline tag {0} was likely intended to be a modifier tag but was not parsed as one due to including content \"{1}\"";
36
37
  readonly failed_to_find_jsdoc_tag_for_name_0: "Failed to find JSDoc tag for {0} after parsing comment, please file a bug report";
37
38
  readonly relative_path_0_is_not_a_file_and_will_not_be_copied_to_output: "The relative path {0} is not a file and will not be copied to the output directory";
38
39
  readonly inline_inheritdoc_should_not_appear_in_block_tag_in_comment_at_0: "An inline @inheritDoc tag should not appear within a block tag as it will not be processed in comment at {0}";
@@ -128,7 +128,7 @@ export declare class Comment {
128
128
  */
129
129
  static combineDisplayParts(parts: readonly CommentDisplayPart[] | undefined): string;
130
130
  /**
131
- * Helper utility to clone {@link Comment.summary} or {@link CommentTag.content}
131
+ * Helper utility to clone {@link Comment#summary} or {@link CommentTag#content}
132
132
  */
133
133
  static cloneDisplayParts(parts: readonly CommentDisplayPart[]): CommentDisplayPart[];
134
134
  static serializeDisplayParts(parts: CommentDisplayPart[]): JSONOutput.CommentDisplayPart[];
@@ -159,7 +159,7 @@ let Comment = (() => {
159
159
  return result;
160
160
  }
161
161
  /**
162
- * Helper utility to clone {@link Comment.summary} or {@link CommentTag.content}
162
+ * Helper utility to clone {@link Comment#summary} or {@link CommentTag#content}
163
163
  */
164
164
  static cloneDisplayParts(parts) {
165
165
  return parts.map((p) => ({ ...p }));
@@ -330,8 +330,12 @@ let MarkedPlugin = (() => {
330
330
  githubAlertMarkdownPlugin(this.parser);
331
331
  const loader = this.application.options.getValue("markdownItLoader");
332
332
  loader(this.parser);
333
+ function defaultRender(tokens, idx, options, _env, self) {
334
+ return self.renderToken(tokens, idx, options);
335
+ }
333
336
  // Add anchor links for headings in readme, and add them to the "On this page" section
334
- this.parser.renderer.rules["heading_open"] = (tokens, idx) => {
337
+ const headingOpenRenderer = this.parser.renderer.rules["heading_open"] || defaultRender;
338
+ this.parser.renderer.rules["heading_open"] = (tokens, idx, options, env, self) => {
335
339
  const token = tokens[idx];
336
340
  const content = getTokenTextContent(tokens[idx + 1]);
337
341
  const level = token.markup.length;
@@ -342,14 +346,16 @@ let MarkedPlugin = (() => {
342
346
  text: content,
343
347
  level,
344
348
  });
345
- return `<${token.tag} id="${slug}" class="tsd-anchor-link">`;
349
+ token.attrSet("id", slug);
350
+ token.attrSet("class", "tsd-anchor-link");
351
+ return headingOpenRenderer(tokens, idx, options, env, self);
346
352
  };
347
- this.parser.renderer.rules["heading_close"] = (tokens, idx) => {
348
- return `${JSX.renderElement(anchorIcon(this.renderContext, this.lastHeaderSlug))}</${tokens[idx].tag}>`;
353
+ const headingCloseRenderer = this.parser.renderer.rules["heading_close"] || defaultRender;
354
+ this.parser.renderer.rules["heading_close"] = (...args) => {
355
+ return `${JSX.renderElement(anchorIcon(this.renderContext, this.lastHeaderSlug))}${headingCloseRenderer(...args)}`;
349
356
  };
350
- // Rewrite anchor links inline in a readme file to links targeting the `md:` prefixed anchors
351
- // that TypeDoc creates.
352
- this.parser.renderer.rules["link_open"] = (tokens, idx, options, _env, self) => {
357
+ const linkOpenRenderer = this.parser.renderer.rules["link_open"] || defaultRender;
358
+ this.parser.renderer.rules["link_open"] = (tokens, idx, options, env, self) => {
353
359
  const token = tokens[idx];
354
360
  const href = token.attrGet("href");
355
361
  if (href) {
@@ -367,8 +373,9 @@ let MarkedPlugin = (() => {
367
373
  }
368
374
  token.attrSet("href", href);
369
375
  }
370
- return self.renderToken(tokens, idx, options);
376
+ return linkOpenRenderer(tokens, idx, options, env, self);
371
377
  };
378
+ // Don't need custom rendering here as this is a TypeDoc-provided rule name
372
379
  this.parser.renderer.rules["alert_open"] = (tokens, idx) => {
373
380
  const icon = this.renderContext.icons[tokens[idx].attrGet("icon")];
374
381
  const iconHtml = JSX.renderElement(icon());
@@ -6,7 +6,7 @@ import { i18n, JSX } from "#utils";
6
6
  const kindIcon = (letterPath, color, label, circular = false) => (JSX.createElement("svg", { class: "tsd-kind-icon", viewBox: "0 0 24 24", "aria-label": label },
7
7
  JSX.createElement("rect", { fill: "var(--color-icon-background)", stroke: color, "stroke-width": "1.5", x: "1", y: "1", width: "22", height: "22", rx: circular ? "12" : "6" }),
8
8
  letterPath));
9
- const textIcon = (letter, color, label, circular = false) => kindIcon(JSX.createElement("text", { fill: "var(--color-icon-text)", x: "50%", y: "50%", "dominant-baseline": "central", "text-anchor": "middle" }, letter), color, label, circular);
9
+ const textIcon = (letter, color, label, circular = false) => kindIcon(JSX.createElement("text", { fill: "var(--color-icon-text)", x: "50%", y: "50%", dy: "0.35em", "text-anchor": "middle" }, letter), color, label, circular);
10
10
  export function buildRefIcons(icons, context) {
11
11
  const refs = {};
12
12
  for (const [name, builder] of Object.entries(icons)) {
@@ -54,7 +54,7 @@ export function inferEntryPoints(logger, options, programs) {
54
54
  for (const [name, path] of pathEntries) {
55
55
  // Strip leading ./ from the display name
56
56
  const displayName = name.replace(/^\.\/?/, "");
57
- const targetPath = jsToTsSource.get(path) || resolveDeclarationMaps(path) || path;
57
+ const targetPath = jsToTsSource.get(normalizePath(path)) || resolveDeclarationMaps(path) || path;
58
58
  const program = programs.find((p) => p.getSourceFile(targetPath));
59
59
  if (program) {
60
60
  entryPoints.push({
@@ -771,6 +771,7 @@ export interface JsxSvgPresentationProps {
771
771
  direction?: "ltr" | "rtl";
772
772
  display?: string;
773
773
  "dominant-baseline"?: "auto" | "text-bottom" | "alphabetic" | "ideographic" | "middle" | "central" | "mathematical" | "hanging" | "text-top";
774
+ dy?: string;
774
775
  fill?: string;
775
776
  "fill-opacity"?: number;
776
777
  "fill-rule"?: "nonzero" | "evenodd";
@@ -1,2 +1,3 @@
1
1
  export declare function setIntersection<T>(a: Iterable<T>, b: Set<T>): Set<T>;
2
2
  export declare function setDifference<T>(a: Iterable<T>, b: Iterable<T>): Set<T>;
3
+ export declare function setUnion<T>(a: Iterable<T>, b: Iterable<T>): Set<T>;
@@ -14,3 +14,10 @@ export function setDifference(a, b) {
14
14
  }
15
15
  return result;
16
16
  }
17
+ export function setUnion(a, b) {
18
+ const result = new Set(a);
19
+ for (const elem of b) {
20
+ result.add(elem);
21
+ }
22
+ return result;
23
+ }
package/package.json CHANGED
@@ -1,12 +1,13 @@
1
1
  {
2
2
  "name": "typedoc",
3
3
  "description": "Create api documentation for TypeScript projects.",
4
- "version": "0.28.15",
4
+ "version": "0.28.16",
5
5
  "homepage": "https://typedoc.org",
6
6
  "type": "module",
7
7
  "exports": {
8
8
  ".": "./dist/index.js",
9
9
  "./tsdoc.json": "./tsdoc.json",
10
+ "./typedoc-config.schema.json": "./typedoc-config.schema.json",
10
11
  "./package.json": "./package.json",
11
12
  "./models": "./dist/lib/models/index.js",
12
13
  "./browser": "./dist/browser-utils.js",
@@ -67,7 +68,8 @@
67
68
  "!/dist/test",
68
69
  "/LICENSE",
69
70
  "/static",
70
- "/tsdoc.json"
71
+ "/tsdoc.json",
72
+ "/typedoc-config.schema.json"
71
73
  ],
72
74
  "keywords": [
73
75
  "typescript",
@@ -121,7 +123,7 @@
121
123
  "build:tsc": "tsc --project .",
122
124
  "build:themes": "node scripts/build_themes.js",
123
125
  "build:locales": "node scripts/build_browser_translations.js",
124
- "build:prod": "pnpm build:prod:tsc && pnpm build:locales && pnpm build:themes",
126
+ "build:prod": "pnpm build:prod:tsc && pnpm build:locales && pnpm build:themes && node scripts/generate_options_schema.js typedoc-config.schema.json",
125
127
  "build:prod:tsc": "tsc --project . --sourceMap false --declarationMap false",
126
128
  "lint": "eslint . --max-warnings 0 && dprint check"
127
129
  }