typedoc 0.28.10 → 0.28.12

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 (39) hide show
  1. package/dist/index.d.ts +1 -1
  2. package/dist/lib/application.js +2 -2
  3. package/dist/lib/converter/comments/discovery.js +26 -3
  4. package/dist/lib/converter/comments/textParser.js +12 -8
  5. package/dist/lib/converter/plugins/CommentPlugin.d.ts +3 -2
  6. package/dist/lib/converter/symbols.js +5 -1
  7. package/dist/lib/internationalization/locales/en.cjs +3 -1
  8. package/dist/lib/internationalization/locales/en.d.cts +3 -1
  9. package/dist/lib/models/Comment.d.ts +15 -15
  10. package/dist/lib/models/Comment.js +12 -5
  11. package/dist/lib/models/DeclarationReflection.js +1 -1
  12. package/dist/lib/models/FileRegistry.js +1 -1
  13. package/dist/lib/models/ProjectReflection.js +2 -2
  14. package/dist/lib/models/Reflection.d.ts +3 -3
  15. package/dist/lib/models/Reflection.js +3 -3
  16. package/dist/lib/output/formatter.js +1 -0
  17. package/dist/lib/output/themes/MarkedPlugin.js +11 -1
  18. package/dist/lib/output/themes/default/partials/comment.js +13 -12
  19. package/dist/lib/output/themes/default/partials/member.declaration.d.ts +1 -1
  20. package/dist/lib/output/themes/default/partials/member.declaration.js +17 -15
  21. package/dist/lib/output/themes/default/partials/member.signature.body.js +1 -1
  22. package/dist/lib/output/themes/default/partials/moduleReflection.js +1 -1
  23. package/dist/lib/output/themes/default/partials/typeDetails.js +21 -19
  24. package/dist/lib/output/themes/default/templates/reflection.js +1 -1
  25. package/dist/lib/serialization/deserializer.d.ts +2 -2
  26. package/dist/lib/serialization/deserializer.js +1 -1
  27. package/dist/lib/serialization/schema.d.ts +3 -3
  28. package/dist/lib/utils/entry-point.js +5 -5
  29. package/dist/lib/utils/options/declaration.d.ts +8 -8
  30. package/dist/lib/utils/options/defaults.d.ts +7 -7
  31. package/dist/lib/utils/options/options.d.ts +3 -3
  32. package/dist/lib/utils/options/options.js +15 -4
  33. package/dist/lib/utils/options/readers/arguments.js +2 -2
  34. package/dist/lib/utils/options/sources/typedoc.js +1 -1
  35. package/dist/lib/utils-common/i18n.d.ts +2 -1
  36. package/dist/lib/utils-common/index.d.ts +1 -0
  37. package/dist/lib/utils-common/validation.d.ts +2 -1
  38. package/package.json +9 -9
  39. package/static/main.js +2 -2
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 NormalizedPathOrModuleOrFunction, 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 TagString, 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";
@@ -409,7 +409,7 @@ let Application = (() => {
409
409
  if (!supportedVersionMajorMinor.some((version) => version == ts.versionMajorMinor)) {
410
410
  this.logger.warn(i18n.unsupported_ts_version_0(supportedVersionMajorMinor.join(", ")));
411
411
  }
412
- if (Object.keys(this.options.getCompilerOptions()).length === 0) {
412
+ if (Object.keys(this.options.getCompilerOptions(this.logger)).length === 0) {
413
413
  this.logger.warn(i18n.no_compiler_options_set());
414
414
  }
415
415
  // Doing this is considerably more complicated, we'd need to manage an array of programs, not convert until all programs
@@ -429,7 +429,7 @@ let Application = (() => {
429
429
  // We don't want to do it the first time to preserve initial debug status messages. They'll be lost
430
430
  // after the user saves a file, but better than nothing...
431
431
  let firstStatusReport = true;
432
- const host = ts.createWatchCompilerHost(tsconfigFile, this.options.fixCompilerOptions({}), ts.sys, ts.createEmitAndSemanticDiagnosticsBuilderProgram, (d) => diagnostic(this.logger, d), (status, newLine, _options, errorCount) => {
432
+ const host = ts.createWatchCompilerHost(tsconfigFile, this.options.fixCompilerOptions({}, this.logger), ts.sys, ts.createEmitAndSemanticDiagnosticsBuilderProgram, (d) => diagnostic(this.logger, d), (status, newLine, _options, errorCount) => {
433
433
  if (!firstStatusReport &&
434
434
  errorCount === void 0 &&
435
435
  !this.options.getValue("preserveWatchOutput") &&
@@ -4,6 +4,7 @@ import { CommentStyle } from "../../utils/options/declaration.js";
4
4
  import { nicePath } from "../../utils/paths.js";
5
5
  import { ok } from "assert";
6
6
  import { assertNever, filter, firstDefined, i18n } from "#utils";
7
+ import { resolveAliasedSymbol } from "../utils/symbols.js";
7
8
  const variablePropertyKinds = [
8
9
  ts.SyntaxKind.PropertyDeclaration,
9
10
  ts.SyntaxKind.PropertySignature,
@@ -263,9 +264,7 @@ function findJsDocForComment(node, ranges) {
263
264
  .map((doc) => ts.findAncestor(doc, ts.isJSDoc));
264
265
  if (ts.isSourceFile(node)) {
265
266
  if (node.statements.length) {
266
- jsDocs.push(...ts
267
- .getJSDocCommentsAndTags(node.statements[0])
268
- .map((doc) => ts.findAncestor(doc, ts.isJSDoc)));
267
+ jsDocs.push(...node.statements[0].getChildren().filter(ts.isJSDoc));
269
268
  }
270
269
  }
271
270
  return jsDocs.find((doc) => doc.pos === ranges[0].pos);
@@ -405,6 +404,30 @@ function declarationToCommentNodes(node, checker) {
405
404
  inheritedFromParentDeclaration: true,
406
405
  });
407
406
  }
407
+ // #2999 automatically pick up comments from the value symbol for shorthand assignments
408
+ if (ts.isShorthandPropertyAssignment(node)) {
409
+ const sourceSymbol = checker.getShorthandAssignmentValueSymbol(node);
410
+ if (sourceSymbol?.valueDeclaration) {
411
+ const commentNode = declarationToCommentNodeIgnoringParents(sourceSymbol.valueDeclaration);
412
+ if (commentNode) {
413
+ result.push({
414
+ node: commentNode,
415
+ inheritedFromParentDeclaration: true,
416
+ });
417
+ }
418
+ }
419
+ // #3003 even more magic for handling an imported symbol which appears in a shorthand property assignment
420
+ const originalSymbol = sourceSymbol && resolveAliasedSymbol(sourceSymbol, checker);
421
+ if (originalSymbol !== sourceSymbol && originalSymbol?.valueDeclaration) {
422
+ const commentNode = declarationToCommentNodeIgnoringParents(originalSymbol?.valueDeclaration);
423
+ if (commentNode) {
424
+ result.push({
425
+ node: commentNode,
426
+ inheritedFromParentDeclaration: true,
427
+ });
428
+ }
429
+ }
430
+ }
408
431
  // With overloaded functions/methods, TypeScript will use the comment on the first signature
409
432
  // declaration
410
433
  if ((ts.isFunctionDeclaration(node) || ts.isMethodDeclaration(node)) &&
@@ -166,8 +166,9 @@ function checkMarkdownLink(data, reentry) {
166
166
  if (link.ok) {
167
167
  // Only make a relative-link display part if it's actually a relative link.
168
168
  // Discard protocol:// links, unix style absolute paths, and windows style absolute paths.
169
- if (isRelativePath(link.str)) {
170
- const { target, anchor } = files.register(sourcePath, link.str) || { target: undefined, anchor: undefined };
169
+ const decoded = decodeURI(link.str);
170
+ if (isRelativePath(decoded)) {
171
+ const { target, anchor } = files.register(sourcePath, decoded) || { target: undefined, anchor: undefined };
171
172
  return {
172
173
  pos: lookahead,
173
174
  end: link.pos,
@@ -213,8 +214,9 @@ function checkReference(data) {
213
214
  }
214
215
  const link = MdHelpers.parseLinkDestination(token.text, lookahead, token.text.length);
215
216
  if (link.ok) {
216
- if (isRelativePath(link.str)) {
217
- const { target, anchor } = files.register(sourcePath, link.str) || { target: undefined, anchor: undefined };
217
+ const decoded = decodeURI(link.str);
218
+ if (isRelativePath(decoded)) {
219
+ const { target, anchor } = files.register(sourcePath, decoded) || { target: undefined, anchor: undefined };
218
220
  return {
219
221
  pos: lookahead,
220
222
  end: link.pos,
@@ -273,8 +275,9 @@ function checkAttributes(data, attributes) {
273
275
  return links;
274
276
  }
275
277
  function checkAttributeDirectPath(data, text, pos, end) {
276
- if (isRelativePath(text.trim())) {
277
- const { target, anchor } = data.files.register(data.sourcePath, text.trim()) || { target: undefined, anchor: undefined };
278
+ const decoded = decodeURI(text.trim());
279
+ if (isRelativePath(decoded)) {
280
+ const { target, anchor } = data.files.register(data.sourcePath, decoded) || { target: undefined, anchor: undefined };
278
281
  return [{
279
282
  pos,
280
283
  end,
@@ -302,8 +305,9 @@ function checkAttributeSrcSet(data, text, pos, _end) {
302
305
  // TypeDoc: We don't exactly match this, PR welcome! For now, just permit anything
303
306
  // that's not whitespace or a comma
304
307
  const url = text.slice(textPos).match(/^[^\t\r\f\n ,]+/);
305
- if (url && isRelativePath(url[0])) {
306
- const { target, anchor } = data.files.register(data.sourcePath, url[0]) || { target: undefined, anchor: undefined };
308
+ const decoded = url && decodeURI(url[0]);
309
+ if (decoded && isRelativePath(decoded)) {
310
+ const { target, anchor } = data.files.register(data.sourcePath, decoded) || { target: undefined, anchor: undefined };
307
311
  result.push({
308
312
  pos: pos + textPos,
309
313
  end: pos + textPos + url[0].length,
@@ -1,3 +1,4 @@
1
+ import { type TagString } from "#utils";
1
2
  import { ConverterComponent } from "../components.js";
2
3
  import type { Converter } from "../converter.js";
3
4
  /**
@@ -56,8 +57,8 @@ import type { Converter } from "../converter.js";
56
57
  * - Resolve `@link` tags to point to target reflections
57
58
  */
58
59
  export declare class CommentPlugin extends ConverterComponent {
59
- accessor excludeTags: `@${string}`[];
60
- accessor cascadedModifierTags: `@${string}`[];
60
+ accessor excludeTags: TagString[];
61
+ accessor cascadedModifierTags: TagString[];
61
62
  accessor excludeInternal: boolean;
62
63
  accessor excludePrivate: boolean;
63
64
  accessor excludeProtected: boolean;
@@ -631,7 +631,11 @@ function convertVariableAsEnum(context, symbol, exportSymbol) {
631
631
  const reflection = context.createDeclarationReflection(ReflectionKind.Enum, symbol, exportSymbol);
632
632
  context.finalizeDeclarationReflection(reflection);
633
633
  const rc = context.withScope(reflection);
634
- const declaration = symbol.declarations.find(ts.isVariableDeclaration);
634
+ const declaration = symbol.valueDeclaration;
635
+ if (!declaration) {
636
+ context.logger.error(i18n.converting_0_as_enum_requires_value_declaration(symbol.name), symbol.declarations?.[0]);
637
+ return;
638
+ }
635
639
  const type = context.checker.getTypeAtLocation(declaration);
636
640
  for (const prop of type.getProperties()) {
637
641
  const reflection = rc.createDeclarationReflection(ReflectionKind.EnumMember, prop, void 0);
@@ -31,6 +31,7 @@ module.exports = {
31
31
  converting_union_as_interface: `Using @interface on a union type will discard properties not present on all branches of the union. TypeDoc's output may not accurately describe your source code`,
32
32
  converting_0_as_class_requires_value_declaration: `Converting {0} as a class requires a declaration which represents a non-type value`,
33
33
  converting_0_as_class_without_construct_signatures: `{0} is being converted as a class, but does not have any construct signatures`,
34
+ converting_0_as_enum_requires_value_declaration: `Converting {0} as an enum requires a declaration which represents a non-type value`,
34
35
  comment_for_0_should_not_contain_block_or_modifier_tags: `The comment for {0} should not contain any block or modifier tags`,
35
36
  symbol_0_has_multiple_declarations_with_comment: `{0} has multiple declarations with a comment. An arbitrary comment will be used`,
36
37
  comments_for_0_are_declared_at_1: `The comments for {0} are declared at:\n\t{1}`,
@@ -144,6 +145,7 @@ module.exports = {
144
145
  invalid_tsdoc_json_0: `The file {0} is not a valid tsdoc.json file`,
145
146
  options_file_0_does_not_exist: `The options file {0} does not exist`,
146
147
  failed_read_options_file_0: `Failed to parse {0}, ensure it exists and exports an object`,
148
+ failed_to_apply_compilerOptions_overrides_0: "Failed to apply compilerOptions overrides: {0}",
147
149
  // plugins
148
150
  invalid_plugin_0_missing_load_function: `Invalid structure in plugin {0}, no load function found`,
149
151
  plugin_0_could_not_be_loaded: `The plugin {0} could not be loaded`,
@@ -360,7 +362,7 @@ module.exports = {
360
362
  // Page headings/labels
361
363
  theme_implements: "Implements",
362
364
  theme_indexable: "Indexable",
363
- theme_type_declaration: "Type declaration",
365
+ theme_type_declaration: "Type Declaration",
364
366
  theme_index: "Index",
365
367
  theme_hierarchy: "Hierarchy",
366
368
  theme_hierarchy_summary: "Hierarchy Summary",
@@ -28,6 +28,7 @@ declare const _default: {
28
28
  readonly converting_union_as_interface: "Using @interface on a union type will discard properties not present on all branches of the union. TypeDoc's output may not accurately describe your source code";
29
29
  readonly converting_0_as_class_requires_value_declaration: "Converting {0} as a class requires a declaration which represents a non-type value";
30
30
  readonly converting_0_as_class_without_construct_signatures: "{0} is being converted as a class, but does not have any construct signatures";
31
+ readonly converting_0_as_enum_requires_value_declaration: "Converting {0} as an enum requires a declaration which represents a non-type value";
31
32
  readonly comment_for_0_should_not_contain_block_or_modifier_tags: "The comment for {0} should not contain any block or modifier tags";
32
33
  readonly symbol_0_has_multiple_declarations_with_comment: "{0} has multiple declarations with a comment. An arbitrary comment will be used";
33
34
  readonly comments_for_0_are_declared_at_1: "The comments for {0} are declared at:\n\t{1}";
@@ -133,6 +134,7 @@ declare const _default: {
133
134
  readonly invalid_tsdoc_json_0: "The file {0} is not a valid tsdoc.json file";
134
135
  readonly options_file_0_does_not_exist: "The options file {0} does not exist";
135
136
  readonly failed_read_options_file_0: "Failed to parse {0}, ensure it exists and exports an object";
137
+ readonly failed_to_apply_compilerOptions_overrides_0: "Failed to apply compilerOptions overrides: {0}";
136
138
  readonly invalid_plugin_0_missing_load_function: "Invalid structure in plugin {0}, no load function found";
137
139
  readonly plugin_0_could_not_be_loaded: "The plugin {0} could not be loaded";
138
140
  readonly help_options: "Specify a json option file that should be loaded. If not specified TypeDoc will look for 'typedoc.json' in the current directory";
@@ -336,7 +338,7 @@ declare const _default: {
336
338
  readonly flag_inherited: "Inherited";
337
339
  readonly theme_implements: "Implements";
338
340
  readonly theme_indexable: "Indexable";
339
- readonly theme_type_declaration: "Type declaration";
341
+ readonly theme_type_declaration: "Type Declaration";
340
342
  readonly theme_index: "Index";
341
343
  readonly theme_hierarchy: "Hierarchy";
342
344
  readonly theme_hierarchy_summary: "Hierarchy Summary";
@@ -1,4 +1,4 @@
1
- import { type NormalizedPath } from "#utils";
1
+ import { type NormalizedPath, type TagString } from "#utils";
2
2
  import type { Reflection } from "./Reflection.js";
3
3
  import { ReflectionSymbolId } from "./ReflectionSymbolId.js";
4
4
  import type { Deserializer, JSONOutput, Serializer } from "#serialization";
@@ -36,7 +36,7 @@ export type CommentDisplayPart =
36
36
  */
37
37
  export interface InlineTagDisplayPart {
38
38
  kind: "inline-tag";
39
- tag: `@${string}`;
39
+ tag: TagString;
40
40
  text: string;
41
41
  target?: Reflection | string | ReflectionSymbolId;
42
42
  tsLinkText?: string;
@@ -79,7 +79,7 @@ export declare class CommentTag {
79
79
  /**
80
80
  * The name of this tag, e.g. `@returns`, `@example`
81
81
  */
82
- tag: `@${string}`;
82
+ tag: TagString;
83
83
  /**
84
84
  * Some tags, (`@typedef`, `@param`, `@property`, etc.) may have a user defined identifier associated with them.
85
85
  * If this tag is one of those, it will be parsed out and included here.
@@ -98,7 +98,7 @@ export declare class CommentTag {
98
98
  /**
99
99
  * Create a new CommentTag instance.
100
100
  */
101
- constructor(tag: `@${string}`, text: CommentDisplayPart[]);
101
+ constructor(tag: TagString, text: CommentDisplayPart[]);
102
102
  /**
103
103
  * Checks if this block tag is roughly equal to the other tag.
104
104
  * This isn't exactly equal, but just "roughly equal" by the tag
@@ -150,7 +150,7 @@ export declare class Comment {
150
150
  /**
151
151
  * All modifier tags present on the comment, e.g. `@alpha`, `@beta`.
152
152
  */
153
- modifierTags: Set<`@${string}`>;
153
+ modifierTags: Set<TagString>;
154
154
  /**
155
155
  * Label associated with this reflection, if any (https://tsdoc.org/pages/tags/label/)
156
156
  */
@@ -179,7 +179,7 @@ export declare class Comment {
179
179
  /**
180
180
  * Creates a new Comment instance.
181
181
  */
182
- constructor(summary?: CommentDisplayPart[], blockTags?: CommentTag[], modifierTags?: Set<`@${string}`>);
182
+ constructor(summary?: CommentDisplayPart[], blockTags?: CommentTag[], modifierTags?: Set<TagString>);
183
183
  /**
184
184
  * Gets either the `@summary` tag, or a short version of the comment summary
185
185
  * section for rendering in module/namespace pages.
@@ -201,36 +201,36 @@ export declare class Comment {
201
201
  */
202
202
  isEmpty(): boolean;
203
203
  /**
204
- * Has this comment a visible component?
204
+ * Checks if this comment contains any visible text.
205
205
  *
206
- * @returns TRUE when this comment has a visible component.
206
+ * @returns TRUE when this reflection has a visible comment.
207
207
  */
208
- hasVisibleComponent(): boolean;
208
+ hasVisibleComponent(notRenderedTags?: readonly TagString[]): boolean;
209
209
  /**
210
210
  * Test whether this comment contains a tag with the given name.
211
211
  *
212
212
  * @param tagName The name of the tag to look for.
213
213
  * @returns TRUE when this comment contains a tag with the given name, otherwise FALSE.
214
214
  */
215
- hasModifier(tagName: `@${string}`): boolean;
216
- removeModifier(tagName: `@${string}`): void;
215
+ hasModifier(tagName: TagString): boolean;
216
+ removeModifier(tagName: TagString): void;
217
217
  /**
218
218
  * Return the first tag with the given name.
219
219
  *
220
220
  * @param tagName The name of the tag to look for.
221
221
  * @returns The found tag or undefined.
222
222
  */
223
- getTag(tagName: `@${string}`): CommentTag | undefined;
223
+ getTag(tagName: TagString): CommentTag | undefined;
224
224
  /**
225
225
  * Get all tags with the given tag name.
226
226
  */
227
- getTags(tagName: `@${string}`): CommentTag[];
228
- getIdentifiedTag(identifier: string, tagName: `@${string}`): CommentTag | undefined;
227
+ getTags(tagName: TagString): CommentTag[];
228
+ getIdentifiedTag(identifier: string, tagName: TagString): CommentTag | undefined;
229
229
  /**
230
230
  * Removes all block tags with the given tag name from the comment.
231
231
  * @param tagName
232
232
  */
233
- removeTags(tagName: `@${string}`): void;
233
+ removeTags(tagName: TagString): void;
234
234
  toObject(serializer: Serializer): JSONOutput.Comment;
235
235
  fromObject(de: Deserializer, obj: JSONOutput.Comment): void;
236
236
  }
@@ -441,13 +441,20 @@ let Comment = (() => {
441
441
  return !this.hasVisibleComponent() && this.modifierTags.size === 0;
442
442
  }
443
443
  /**
444
- * Has this comment a visible component?
444
+ * Checks if this comment contains any visible text.
445
445
  *
446
- * @returns TRUE when this comment has a visible component.
446
+ * @returns TRUE when this reflection has a visible comment.
447
447
  */
448
- hasVisibleComponent() {
449
- return (this.summary.some((x) => x.kind !== "text" || x.text !== "") ||
450
- this.blockTags.length > 0);
448
+ hasVisibleComponent(notRenderedTags) {
449
+ if (this.summary.some((x) => x.kind !== "text" || x.text !== "")) {
450
+ return true;
451
+ }
452
+ if (notRenderedTags) {
453
+ return this.blockTags.some(tag => !notRenderedTags.includes(tag.tag));
454
+ }
455
+ else {
456
+ return this.blockTags.length > 0;
457
+ }
451
458
  }
452
459
  /**
453
460
  * Test whether this comment contains a tag with the given name.
@@ -252,7 +252,7 @@ export class DeclarationReflection extends ContainerReflection {
252
252
  this.project.registerSymbolId(refl, new ReflectionSymbolId(sid));
253
253
  }
254
254
  else {
255
- de.logger.warn(i18n.serialized_project_referenced_0_not_part_of_project(id.toString()));
255
+ de.logger.warn(i18n.serialized_project_referenced_0_not_part_of_project(id));
256
256
  }
257
257
  }
258
258
  });
@@ -55,7 +55,7 @@ export class FileRegistry {
55
55
  }
56
56
  resolve(id, project) {
57
57
  const reflId = this.mediaToReflection.get(id);
58
- if (reflId) {
58
+ if (typeof reflId === "number") {
59
59
  return project.getReflectionById(reflId);
60
60
  }
61
61
  return this.mediaToPath.get(id);
@@ -342,7 +342,7 @@ let ProjectReflection = (() => {
342
342
  this.removedSymbolIds.delete(id);
343
343
  this.reflectionIdToSymbolIdMap.set(reflection.id, id);
344
344
  const previous = this.symbolToReflectionIdMap.get(id);
345
- if (previous) {
345
+ if (typeof previous !== "undefined") {
346
346
  if (typeof previous === "number") {
347
347
  this.symbolToReflectionIdMap.set(id, [previous, reflection.id]);
348
348
  }
@@ -407,7 +407,7 @@ let ProjectReflection = (() => {
407
407
  this.registerSymbolId(refl, new ReflectionSymbolId(sid));
408
408
  }
409
409
  else {
410
- de.logger.warn(i18n.serialized_project_referenced_0_not_part_of_project(id.toString()));
410
+ de.logger.warn(i18n.serialized_project_referenced_0_not_part_of_project(id));
411
411
  }
412
412
  }
413
413
  });
@@ -1,6 +1,6 @@
1
1
  import { Comment } from "./Comment.js";
2
2
  import type { ProjectReflection } from "./ProjectReflection.js";
3
- import { type NeverIfInternal, type TranslatedString } from "#utils";
3
+ import { type NeverIfInternal, type TagString, type TranslatedString } from "#utils";
4
4
  import { ReflectionKind } from "./kind.js";
5
5
  import type { Deserializer, JSONOutput, Serializer } from "#serialization";
6
6
  import type { ReflectionVariant } from "./variant.js";
@@ -171,11 +171,11 @@ export declare abstract class Reflection {
171
171
  */
172
172
  setFlag(flag: ReflectionFlag, value?: boolean): void;
173
173
  /**
174
- * Has this reflection a visible comment?
174
+ * Checks if this reflection has a comment which contains any visible text.
175
175
  *
176
176
  * @returns TRUE when this reflection has a visible comment.
177
177
  */
178
- hasComment(): boolean;
178
+ hasComment(notRenderedTags?: readonly TagString[]): boolean;
179
179
  hasGetterOrSetter(): boolean;
180
180
  /**
181
181
  * Return a child by its name.
@@ -359,12 +359,12 @@ let Reflection = (() => {
359
359
  this.flags.setFlag(flag, value);
360
360
  }
361
361
  /**
362
- * Has this reflection a visible comment?
362
+ * Checks if this reflection has a comment which contains any visible text.
363
363
  *
364
364
  * @returns TRUE when this reflection has a visible comment.
365
365
  */
366
- hasComment() {
367
- return this.comment ? this.comment.hasVisibleComponent() : false;
366
+ hasComment(notRenderedTags) {
367
+ return this.comment ? this.comment.hasVisibleComponent(notRenderedTags) : false;
368
368
  }
369
369
  hasGetterOrSetter() {
370
370
  return false;
@@ -566,6 +566,7 @@ export class FormattedCodeBuilder {
566
566
  const id = this.newId();
567
567
  return group(id, [
568
568
  name,
569
+ sig.parent.flags.isOptional ? simpleElement(JSX.createElement("span", { class: "tsd-signature-symbol" }, "?")) : emptyNode,
569
570
  this.typeParameters(sig),
570
571
  ...this.parameters(sig, id),
571
572
  nodes(options.arrowStyle ? space() : emptyNode, simpleElement(JSX.createElement("span", { class: "tsd-signature-symbol" }, options.arrowStyle ? "=>" : ":")), space(), this.type(sig.type, TypeContext.none)),
@@ -240,7 +240,17 @@ let MarkedPlugin = (() => {
240
240
  const refl = page.project.files.resolve(part.target, page.model.project);
241
241
  let url;
242
242
  if (typeof refl === "object") {
243
- url = context.urlTo(refl);
243
+ // #3006, this is an unfortunate heuristic. If there is a relative link to the project
244
+ // the user probably created it by linking to the directory of the project or to
245
+ // the project's readme. Since the readme doesn't get its own reflection, we can't
246
+ // reliably disambiguate this and instead will arbitrarily decide to reference the
247
+ // root index page in this case.
248
+ if (refl.isProject()) {
249
+ url = context.relativeURL("./");
250
+ }
251
+ else {
252
+ url = context.urlTo(refl);
253
+ }
244
254
  }
245
255
  else {
246
256
  const fileName = page.project.files.getName(part.target);
@@ -48,20 +48,21 @@ export function commentTags(context, props) {
48
48
  ? props.comment.blockTags.filter((tag) => tag.tag !== "@returns" && !tag.skipRendering && !skippedTags.includes(tag.tag))
49
49
  : props.comment.blockTags.filter((tag) => !tag.skipRendering && !skippedTags.includes(tag.tag));
50
50
  skipSave.forEach((skip, i) => (props.comment.blockTags[i].skipRendering = skip));
51
+ const tagsContents = tags.map((item) => {
52
+ const name = item.name
53
+ ? `${translateTagName(item.tag)}: ${item.name}`
54
+ : translateTagName(item.tag);
55
+ const anchor = context.slugger.slug(name);
56
+ return (JSX.createElement(JSX.Fragment, null,
57
+ JSX.createElement("div", { class: `tsd-tag-${item.tag.substring(1)}` },
58
+ JSX.createElement("h4", { class: "tsd-anchor-link", id: anchor },
59
+ name,
60
+ anchorIcon(context, anchor)),
61
+ JSX.createElement(JSX.Raw, { html: context.markdown(item.content) }))));
62
+ });
51
63
  return (JSX.createElement(JSX.Fragment, null,
52
64
  beforeTags,
53
- JSX.createElement("div", { class: "tsd-comment tsd-typography" }, tags.map((item) => {
54
- const name = item.name
55
- ? `${translateTagName(item.tag)}: ${item.name}`
56
- : translateTagName(item.tag);
57
- const anchor = context.slugger.slug(name);
58
- return (JSX.createElement(JSX.Fragment, null,
59
- JSX.createElement("div", { class: `tsd-tag-${item.tag.substring(1)}` },
60
- JSX.createElement("h4", { class: "tsd-anchor-link", id: anchor },
61
- name,
62
- anchorIcon(context, anchor)),
63
- JSX.createElement(JSX.Raw, { html: context.markdown(item.content) }))));
64
- })),
65
+ tagsContents.length > 0 && (JSX.createElement("div", { class: "tsd-comment tsd-typography" }, tagsContents)),
65
66
  afterTags));
66
67
  }
67
68
  export function reflectionFlags(context, props) {
@@ -1,4 +1,4 @@
1
- import type { DeclarationReflection } from "../../../../models/index.js";
1
+ import type { DeclarationReflection } from "#models";
2
2
  import { JSX } from "#utils";
3
3
  import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext.js";
4
4
  export declare function memberDeclaration(context: DefaultThemeRenderContext, props: DeclarationReflection): JSX.Element;
@@ -1,30 +1,32 @@
1
1
  import { JSX } from "#utils";
2
2
  import { FormattedCodeBuilder, FormattedCodeGenerator, Wrap } from "../../../formatter.js";
3
3
  import { hasTypeParameters } from "../../lib.js";
4
+ function shouldRenderDefaultValue(props) {
5
+ const defaultValue = props.defaultValue;
6
+ if (defaultValue === undefined) {
7
+ return false;
8
+ }
9
+ /** Fix for #2717. If type is the same as value the default value is omitted */
10
+ if (props.type && props.type.type === "literal") {
11
+ const reflectionTypeString = props.type.toString();
12
+ if (reflectionTypeString === defaultValue) {
13
+ return false;
14
+ }
15
+ }
16
+ return true;
17
+ }
4
18
  export function memberDeclaration(context, props) {
5
19
  const builder = new FormattedCodeBuilder(context.router, context.model);
6
20
  const content = [];
7
21
  builder.member(content, props, { topLevelLinks: false });
8
22
  const generator = new FormattedCodeGenerator(context.options.getValue("typePrintWidth"));
9
23
  generator.node({ type: "nodes", content }, Wrap.Detect);
10
- /** Fix for #2717. If type is the same as value the default value is omitted */
11
- function shouldRenderDefaultValue() {
12
- if (props.type && props.type.type === "literal") {
13
- const reflectionTypeString = props.type.toString();
14
- const defaultValue = props.defaultValue;
15
- if (defaultValue === undefined || reflectionTypeString === defaultValue.toString()) {
16
- return false;
17
- }
18
- }
19
- return true;
20
- }
21
24
  return (JSX.createElement(JSX.Fragment, null,
22
25
  JSX.createElement("div", { class: "tsd-signature" },
23
26
  generator.toElement(),
24
- !!props.defaultValue && shouldRenderDefaultValue() && (JSX.createElement(JSX.Fragment, null,
25
- JSX.createElement("span", { class: "tsd-signature-symbol" },
26
- " = ",
27
- props.defaultValue)))),
27
+ shouldRenderDefaultValue(props) && (JSX.createElement("span", { class: "tsd-signature-symbol" },
28
+ " = ",
29
+ props.defaultValue))),
28
30
  context.commentSummary(props),
29
31
  hasTypeParameters(props) && context.typeParameters(props.typeParameters),
30
32
  props.type && context.typeDeclaration(props, props.type),
@@ -11,7 +11,7 @@ export function memberSignatureBody(context, props, { hideSources = false } = {}
11
11
  JSX.createElement("ul", { class: "tsd-parameter-list" }, props.parameters.map((item) => (JSX.createElement("li", null,
12
12
  JSX.createElement("span", null,
13
13
  context.reflectionFlags(item),
14
- !!item.flags.isRest && JSX.createElement("span", { class: "tsd-signature-symbol" }, "..."),
14
+ item.flags.isRest && JSX.createElement("span", { class: "tsd-signature-symbol" }, "..."),
15
15
  JSX.createElement("span", { class: "tsd-kind-parameter" }, item.name),
16
16
  ": ",
17
17
  context.type(item.type),
@@ -5,7 +5,7 @@ import { anchorIcon } from "./anchor-icon.js";
5
5
  export function moduleReflection(context, mod) {
6
6
  const sections = getMemberSections(mod);
7
7
  return (JSX.createElement(JSX.Fragment, null,
8
- mod.hasComment() && (JSX.createElement("section", { class: "tsd-panel tsd-comment" },
8
+ mod.hasComment(context.options.getValue("notRenderedTags")) && (JSX.createElement("section", { class: "tsd-panel tsd-comment" },
9
9
  context.commentSummary(mod),
10
10
  context.commentTags(mod))),
11
11
  mod.isDeclaration() && mod.kind === ReflectionKind.Module && !!mod.readme?.length && (JSX.createElement("section", { class: "tsd-panel tsd-typography" },