typedoc 0.23.0-beta.5 → 0.23.0

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/dist/index.d.ts +1 -1
  2. package/dist/index.js +2 -1
  3. package/dist/lib/converter/comments/blockLexer.js +1 -1
  4. package/dist/lib/converter/comments/declarationReference.d.ts +2 -4
  5. package/dist/lib/converter/comments/declarationReference.js +18 -2
  6. package/dist/lib/converter/comments/declarationReferenceResolver.d.ts +3 -0
  7. package/dist/lib/converter/comments/declarationReferenceResolver.js +177 -0
  8. package/dist/lib/converter/comments/lineLexer.js +1 -1
  9. package/dist/lib/converter/comments/parser.js +1 -1
  10. package/dist/lib/converter/comments/rawLexer.js +1 -1
  11. package/dist/lib/converter/plugins/CategoryPlugin.d.ts +4 -5
  12. package/dist/lib/converter/plugins/CategoryPlugin.js +26 -11
  13. package/dist/lib/converter/plugins/CommentPlugin.js +5 -1
  14. package/dist/lib/converter/plugins/GroupPlugin.d.ts +4 -2
  15. package/dist/lib/converter/plugins/GroupPlugin.js +28 -4
  16. package/dist/lib/converter/plugins/InheritDocPlugin.js +7 -1
  17. package/dist/lib/converter/plugins/LinkResolverPlugin.js +2 -170
  18. package/dist/lib/converter/plugins/PackagePlugin.js +5 -1
  19. package/dist/lib/converter/symbols.js +5 -3
  20. package/dist/lib/models/reflections/abstract.d.ts +7 -0
  21. package/dist/lib/models/reflections/abstract.js +12 -0
  22. package/dist/lib/models/reflections/container.d.ts +2 -2
  23. package/dist/lib/output/plugins/JavascriptIndexPlugin.js +1 -6
  24. package/dist/lib/output/themes/default/DefaultTheme.js +7 -1
  25. package/dist/lib/output/themes/default/partials/index.js +1 -1
  26. package/dist/lib/output/themes/default/partials/member.js +1 -1
  27. package/dist/lib/output/themes/default/partials/navigation.js +13 -10
  28. package/dist/lib/utils/index.d.ts +1 -1
  29. package/dist/lib/utils/index.js +2 -1
  30. package/dist/lib/utils/options/declaration.d.ts +9 -19
  31. package/dist/lib/utils/options/declaration.js +4 -6
  32. package/dist/lib/utils/options/index.d.ts +1 -1
  33. package/dist/lib/utils/options/index.js +2 -1
  34. package/dist/lib/utils/options/sources/typedoc.js +163 -151
  35. package/dist/lib/utils/options/tsdoc-defaults.d.ts +5 -5
  36. package/dist/lib/utils/options/tsdoc-defaults.js +12 -1
  37. package/dist/lib/utils/package-manifest.js +4 -2
  38. package/package.json +3 -5
  39. package/static/main.js +3 -3
  40. package/static/style.css +6 -5
  41. package/{.config/typedoc-default.tsdoc.json → tsdoc.json} +33 -0
package/dist/index.d.ts CHANGED
@@ -6,7 +6,7 @@ export * from "./lib/models";
6
6
  export { Converter, Context, type CommentParserConfig } from "./lib/converter";
7
7
  export { Renderer, DefaultTheme, DefaultThemeRenderContext, UrlMapping, Theme, PageEvent, RendererEvent, MarkdownEvent, } from "./lib/output";
8
8
  export type { RenderTemplate, RendererHooks } from "./lib/output";
9
- export { ArgumentsReader, BindOption, JSX, LogLevel, Logger, Options, ParameterHint, ParameterType, TSConfigReader, TypeDocReader, EntryPointStrategy, EventHooks, } from "./lib/utils";
9
+ export { ArgumentsReader, BindOption, CommentStyle, JSX, LogLevel, Logger, Options, ParameterHint, ParameterType, TSConfigReader, TypeDocReader, EntryPointStrategy, EventHooks, } from "./lib/utils";
10
10
  export type { OptionsReader, TypeDocOptions, TypeDocOptionMap, ValidationOptions, TypeDocOptionValues, KeyToDeclaration, DeclarationOption, DeclarationOptionBase, StringDeclarationOption, NumberDeclarationOption, BooleanDeclarationOption, ArrayDeclarationOption, MixedDeclarationOption, MapDeclarationOption, FlagsDeclarationOption, DeclarationOptionToOptionType, SortStrategy, ParameterTypeToOptionTypeMap, DocumentationEntryPoint, ManuallyValidatedOption, } from "./lib/utils";
11
11
  export type { EventMap, EventCallback } from "./lib/utils/events";
12
12
  export { JSONOutput, Serializer, type SerializerComponent, SerializeEvent, } from "./lib/serialization";
package/dist/index.js CHANGED
@@ -14,7 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.TypeScript = exports.SerializeEvent = exports.Serializer = exports.JSONOutput = exports.EventHooks = exports.EntryPointStrategy = exports.TypeDocReader = exports.TSConfigReader = exports.ParameterType = exports.ParameterHint = exports.Options = exports.Logger = exports.LogLevel = exports.JSX = exports.BindOption = exports.ArgumentsReader = exports.MarkdownEvent = exports.RendererEvent = exports.PageEvent = exports.Theme = exports.UrlMapping = exports.DefaultThemeRenderContext = exports.DefaultTheme = exports.Renderer = exports.Context = exports.Converter = exports.normalizePath = exports.resetReflectionID = exports.Event = exports.EventDispatcher = exports.Application = void 0;
17
+ exports.TypeScript = exports.SerializeEvent = exports.Serializer = exports.JSONOutput = exports.EventHooks = exports.EntryPointStrategy = exports.TypeDocReader = exports.TSConfigReader = exports.ParameterType = exports.ParameterHint = exports.Options = exports.Logger = exports.LogLevel = exports.JSX = exports.CommentStyle = exports.BindOption = exports.ArgumentsReader = exports.MarkdownEvent = exports.RendererEvent = exports.PageEvent = exports.Theme = exports.UrlMapping = exports.DefaultThemeRenderContext = exports.DefaultTheme = exports.Renderer = exports.Context = exports.Converter = exports.normalizePath = exports.resetReflectionID = exports.Event = exports.EventDispatcher = exports.Application = void 0;
18
18
  var application_1 = require("./lib/application");
19
19
  Object.defineProperty(exports, "Application", { enumerable: true, get: function () { return application_1.Application; } });
20
20
  var events_1 = require("./lib/utils/events");
@@ -40,6 +40,7 @@ Object.defineProperty(exports, "MarkdownEvent", { enumerable: true, get: functio
40
40
  var utils_1 = require("./lib/utils");
41
41
  Object.defineProperty(exports, "ArgumentsReader", { enumerable: true, get: function () { return utils_1.ArgumentsReader; } });
42
42
  Object.defineProperty(exports, "BindOption", { enumerable: true, get: function () { return utils_1.BindOption; } });
43
+ Object.defineProperty(exports, "CommentStyle", { enumerable: true, get: function () { return utils_1.CommentStyle; } });
43
44
  Object.defineProperty(exports, "JSX", { enumerable: true, get: function () { return utils_1.JSX; } });
44
45
  Object.defineProperty(exports, "LogLevel", { enumerable: true, get: function () { return utils_1.LogLevel; } });
45
46
  Object.defineProperty(exports, "Logger", { enumerable: true, get: function () { return utils_1.Logger; } });
@@ -230,7 +230,7 @@ function* lexBlockComment2(file, pos, end) {
230
230
  return lookahead;
231
231
  }
232
232
  function lookaheadExactlyNTicks(pos, n) {
233
- if (pos + n >= end) {
233
+ if (pos + n > end) {
234
234
  return false;
235
235
  }
236
236
  return file.startsWith("`".repeat(n), pos) && file[pos + n] !== "`";
@@ -14,6 +14,7 @@ export interface DeclarationReference {
14
14
  }
15
15
  export interface Meaning {
16
16
  keyword?: MeaningKeyword;
17
+ label?: string;
17
18
  index?: number;
18
19
  }
19
20
  export interface SymbolReference {
@@ -35,8 +36,5 @@ export declare function parseModuleSource(source: string, pos: number, end: numb
35
36
  export declare function parseSymbolReference(source: string, pos: number, end: number): [SymbolReference, number] | undefined;
36
37
  export declare function parseComponent(source: string, pos: number, end: number): [string, number] | undefined;
37
38
  export declare function parseComponentPath(source: string, pos: number, end: number): readonly [ComponentPath[], number] | undefined;
38
- export declare function parseMeaning(source: string, pos: number, end: number): [{
39
- keyword?: MeaningKeyword;
40
- index?: number;
41
- }, number] | undefined;
39
+ export declare function parseMeaning(source: string, pos: number, end: number): [Meaning, number] | undefined;
42
40
  export declare function parseDeclarationReference(source: string, pos: number, end: number): [DeclarationReference, number] | undefined;
@@ -34,6 +34,8 @@ const DecimalDigit = "0123456789";
34
34
  const HexDigit = DecimalDigit + "abcdefABCDEF";
35
35
  const SingleEscapeCharacter = `'"\\bfnrtv`;
36
36
  const EscapeCharacter = SingleEscapeCharacter + DecimalDigit + "xu";
37
+ const UserLabelStart = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_";
38
+ const UserLabelCharacter = UserLabelStart + DecimalDigit;
37
39
  const SingleEscapeChars = {
38
40
  "'": "'",
39
41
  '"': '"',
@@ -217,11 +219,17 @@ function parseComponentPath(source, pos, end) {
217
219
  return [components, pos];
218
220
  }
219
221
  exports.parseComponentPath = parseComponentPath;
222
+ // The TSDoc specification permits the first four branches of Meaning. TypeDoc adds the UserLabel
223
+ // branch so that the @label tag can be used with this form of declaration references.
220
224
  // Meaning:
221
225
  // `:` MeaningKeyword // Indicates the meaning of a symbol (i.e. ':class')
222
226
  // `:` MeaningKeyword `(` DecimalDigits `)` // Indicates an overloaded meaning (i.e. ':function(1)')
223
227
  // `:` `(` DecimalDigits `)` // Shorthand for an overloaded meaning (i.e. `:(1)`)
224
228
  // `:` DecimalDigits // Shorthand for an overloaded meaning (i.e. ':1')
229
+ // `:` UserLabel // Indicates a user defined label via {@label CUSTOM_LABEL}
230
+ //
231
+ // UserLabel:
232
+ // UserLabelStart UserLabelCharacter*
225
233
  function parseMeaning(source, pos, end) {
226
234
  if (source[pos++] !== ":")
227
235
  return;
@@ -229,6 +237,14 @@ function parseMeaning(source, pos, end) {
229
237
  if (keyword) {
230
238
  pos += keyword.length;
231
239
  }
240
+ if (!keyword && UserLabelStart.includes(source[pos])) {
241
+ let lookahead = pos + 1;
242
+ while (lookahead < end &&
243
+ UserLabelCharacter.includes(source[lookahead])) {
244
+ lookahead++;
245
+ }
246
+ return [{ label: source.substring(pos, lookahead) }, lookahead];
247
+ }
232
248
  if (pos + 1 < end &&
233
249
  source[pos] === "(" &&
234
250
  DecimalDigit.includes(source[pos + 1])) {
@@ -242,7 +258,7 @@ function parseMeaning(source, pos, end) {
242
258
  keyword,
243
259
  index: parseInt(source.substring(pos + 1, lookahead)),
244
260
  },
245
- pos,
261
+ lookahead + 1,
246
262
  ];
247
263
  }
248
264
  }
@@ -255,7 +271,7 @@ function parseMeaning(source, pos, end) {
255
271
  {
256
272
  index: parseInt(source.substring(pos, lookahead)),
257
273
  },
258
- pos,
274
+ lookahead,
259
275
  ];
260
276
  }
261
277
  if (keyword) {
@@ -0,0 +1,3 @@
1
+ import { Reflection } from "../../models";
2
+ import type { DeclarationReference } from "./declarationReference";
3
+ export declare function resolveDeclarationReference(reflection: Reflection, ref: DeclarationReference): Reflection | undefined;
@@ -0,0 +1,177 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resolveDeclarationReference = void 0;
4
+ const assert_1 = require("assert");
5
+ const models_1 = require("../../models");
6
+ const utils_1 = require("../../utils");
7
+ function resolveDeclarationReference(reflection, ref) {
8
+ let high = [];
9
+ let low = [];
10
+ if (ref.moduleSource) {
11
+ high =
12
+ reflection.project.children?.filter((c) => c.kindOf(models_1.ReflectionKind.SomeModule) &&
13
+ c.name === ref.moduleSource) || [];
14
+ }
15
+ else if (ref.resolutionStart === "global") {
16
+ high.push(reflection.project);
17
+ }
18
+ else {
19
+ (0, assert_1.ok)(ref.resolutionStart === "local");
20
+ // TypeScript's behavior is to first try to resolve links via variable scope, and then
21
+ // if the link still hasn't been found, check either siblings (if comment belongs to a member)
22
+ // or otherwise children.
23
+ let refl = reflection;
24
+ if (refl.kindOf(models_1.ReflectionKind.ExportContainer)) {
25
+ high.push(refl);
26
+ }
27
+ while (refl.parent) {
28
+ refl = refl.parent;
29
+ if (refl.kindOf(models_1.ReflectionKind.ExportContainer)) {
30
+ high.push(refl);
31
+ }
32
+ }
33
+ if (reflection.kindOf(models_1.ReflectionKind.SomeMember)) {
34
+ high.push(reflection.parent);
35
+ }
36
+ else if (reflection.kindOf(models_1.ReflectionKind.SomeSignature) &&
37
+ reflection.parent.kindOf(models_1.ReflectionKind.SomeMember)) {
38
+ high.push(reflection.parent.parent);
39
+ }
40
+ else if (high[0] !== reflection) {
41
+ high.push(reflection);
42
+ }
43
+ }
44
+ if (ref.symbolReference) {
45
+ for (const part of ref.symbolReference.path || []) {
46
+ const high2 = high;
47
+ high = [];
48
+ const low2 = low;
49
+ low = [];
50
+ for (const refl of high2) {
51
+ const resolved = resolveSymbolReferencePart(refl, part);
52
+ high.push(...resolved.high);
53
+ low.push(...resolved.low);
54
+ }
55
+ for (const refl of low2) {
56
+ const resolved = resolveSymbolReferencePart(refl, part);
57
+ low.push(...resolved.high);
58
+ low.push(...resolved.low);
59
+ }
60
+ }
61
+ if (ref.symbolReference.meaning) {
62
+ high = filterMapByMeaning(high, ref.symbolReference.meaning);
63
+ low = filterMapByMeaning(low, ref.symbolReference.meaning);
64
+ }
65
+ }
66
+ return high[0] || low[0];
67
+ }
68
+ exports.resolveDeclarationReference = resolveDeclarationReference;
69
+ function filterMapByMeaning(reflections, meaning) {
70
+ return (0, utils_1.filterMap)(reflections, (refl) => {
71
+ const kwResolved = resolveKeyword(refl, meaning.keyword) || [];
72
+ if (meaning.label) {
73
+ return kwResolved.find((r) => r.label === meaning.label);
74
+ }
75
+ return kwResolved[meaning.index || 0];
76
+ });
77
+ }
78
+ function resolveKeyword(refl, kw) {
79
+ switch (kw) {
80
+ case undefined:
81
+ return refl instanceof models_1.DeclarationReflection && refl.signatures
82
+ ? refl.signatures
83
+ : [refl];
84
+ case "class":
85
+ if (refl.kindOf(models_1.ReflectionKind.Class))
86
+ return [refl];
87
+ break;
88
+ case "interface":
89
+ if (refl.kindOf(models_1.ReflectionKind.Interface))
90
+ return [refl];
91
+ break;
92
+ case "type":
93
+ if (refl.kindOf(models_1.ReflectionKind.SomeType))
94
+ return [refl];
95
+ break;
96
+ case "enum":
97
+ if (refl.kindOf(models_1.ReflectionKind.Enum))
98
+ return [refl];
99
+ break;
100
+ case "namespace":
101
+ if (refl.kindOf(models_1.ReflectionKind.SomeModule))
102
+ return [refl];
103
+ break;
104
+ case "function":
105
+ if (refl.kindOf(models_1.ReflectionKind.FunctionOrMethod)) {
106
+ return refl.signatures;
107
+ }
108
+ break;
109
+ case "var":
110
+ if (refl.kindOf(models_1.ReflectionKind.Variable))
111
+ return [refl];
112
+ break;
113
+ case "new":
114
+ case "constructor":
115
+ if (refl.kindOf(models_1.ReflectionKind.ClassOrInterface | models_1.ReflectionKind.TypeLiteral)) {
116
+ const ctor = refl.children?.find((c) => c.kindOf(models_1.ReflectionKind.Constructor));
117
+ return ctor?.signatures;
118
+ }
119
+ break;
120
+ case "member":
121
+ if (refl.kindOf(models_1.ReflectionKind.SomeMember))
122
+ return [refl];
123
+ break;
124
+ case "event":
125
+ // Never resolve. Nobody should use this.
126
+ // It's required by the grammar, but is not documented by TypeDoc
127
+ // nor by the comments in the grammar.
128
+ break;
129
+ case "call":
130
+ return refl.signatures;
131
+ case "index":
132
+ if (refl.indexSignature) {
133
+ return [refl.indexSignature];
134
+ }
135
+ break;
136
+ case "complex":
137
+ if (refl.kindOf(models_1.ReflectionKind.SomeType))
138
+ return [refl];
139
+ break;
140
+ }
141
+ }
142
+ function resolveSymbolReferencePart(refl, path) {
143
+ let high = [];
144
+ let low = [];
145
+ if (!(refl instanceof models_1.ContainerReflection) || !refl.children) {
146
+ return { high, low };
147
+ }
148
+ switch (path.navigation) {
149
+ // Grammar says resolve via "exports"... as always, reality is more complicated.
150
+ // Check exports first, but also allow this as a general purpose "some child" operator
151
+ // so that resolution doesn't behave very poorly with projects using JSDoc style resolution.
152
+ // Also is more consistent with how TypeScript resolves link tags.
153
+ case ".":
154
+ high = refl.children.filter((r) => r.name === path.path &&
155
+ (r.kindOf(models_1.ReflectionKind.SomeExport) || r.flags.isStatic));
156
+ low = refl.children.filter((r) => r.name === path.path &&
157
+ (!r.kindOf(models_1.ReflectionKind.SomeExport) || !r.flags.isStatic));
158
+ break;
159
+ // Resolve via "members", interface children, class instance properties/accessors/methods,
160
+ // enum members, type literal properties
161
+ case "#":
162
+ high = refl.children.filter((r) => {
163
+ return (r.name === path.path &&
164
+ r.kindOf(models_1.ReflectionKind.SomeMember) &&
165
+ !r.flags.isStatic);
166
+ });
167
+ break;
168
+ // Resolve via "locals"... treat this as a stricter `.` which only supports traversing
169
+ // module/namespace exports since TypeDoc doesn't support documenting locals.
170
+ case "~":
171
+ if (refl.kindOf(models_1.ReflectionKind.SomeModule | models_1.ReflectionKind.Project)) {
172
+ high = refl.children.filter((r) => r.name === path.path);
173
+ }
174
+ break;
175
+ }
176
+ return { high, low };
177
+ }
@@ -200,7 +200,7 @@ function* lexBlockComment2(file, pos, end) {
200
200
  return lookahead;
201
201
  }
202
202
  function lookaheadExactlyNTicks(pos, n) {
203
- if (pos + n >= end) {
203
+ if (pos + n > end) {
204
204
  return false;
205
205
  }
206
206
  return file.startsWith("`".repeat(n), pos) && file[pos + n] !== "`";
@@ -153,7 +153,7 @@ function blockContent(comment, lexer, config, warning) {
153
153
  break;
154
154
  case lexer_1.TokenSyntaxKind.Tag:
155
155
  if (next.text === "@inheritdoc") {
156
- warning("The @inheritDoc tag should be properly capitalized.");
156
+ warning("The @inheritDoc tag should be properly capitalized");
157
157
  next.text = "@inheritDoc";
158
158
  }
159
159
  if (config.modifierTags.has(next.text)) {
@@ -191,7 +191,7 @@ function* lexCommentString2(file) {
191
191
  };
192
192
  }
193
193
  function lookaheadExactlyNTicks(pos, n) {
194
- if (pos + n >= end) {
194
+ if (pos + n > end) {
195
195
  return false;
196
196
  }
197
197
  return file.startsWith("`".repeat(n), pos) && file[pos + n] !== "`";
@@ -10,7 +10,8 @@ export declare class CategoryPlugin extends ConverterComponent {
10
10
  defaultCategory: string;
11
11
  categoryOrder: string[];
12
12
  categorizeByGroup: boolean;
13
- searchCategoryBoosts: Record<string, number> | undefined;
13
+ boosts: Record<string, number>;
14
+ usedBoosts: Set<string>;
14
15
  static defaultCategory: string;
15
16
  static WEIGHTS: string[];
16
17
  /**
@@ -45,9 +46,7 @@ export declare class CategoryPlugin extends ConverterComponent {
45
46
  * relevance boost to be used when searching
46
47
  * @returns An array containing all children of the given reflection categorized
47
48
  */
48
- static getReflectionCategories(reflections: DeclarationReflection[], categorySearchBoosts: {
49
- [key: string]: number;
50
- } | undefined): ReflectionCategory[];
49
+ getReflectionCategories(reflections: DeclarationReflection[]): ReflectionCategory[];
51
50
  /**
52
51
  * Return the category of a given reflection.
53
52
  *
@@ -57,7 +56,7 @@ export declare class CategoryPlugin extends ConverterComponent {
57
56
  * @privateRemarks
58
57
  * If you change this, also update getGroups in GroupPlugin accordingly.
59
58
  */
60
- static getCategories(reflection: DeclarationReflection): Set<string>;
59
+ getCategories(reflection: DeclarationReflection): Set<string>;
61
60
  /**
62
61
  * Callback used to sort categories by name.
63
62
  *
@@ -19,6 +19,10 @@ const utils_1 = require("../../utils");
19
19
  * The handler sets the ´category´ property of all reflections.
20
20
  */
21
21
  let CategoryPlugin = CategoryPlugin_1 = class CategoryPlugin extends components_1.ConverterComponent {
22
+ constructor() {
23
+ super(...arguments);
24
+ this.usedBoosts = new Set();
25
+ }
22
26
  /**
23
27
  * Create a new CategoryPlugin instance.
24
28
  */
@@ -60,6 +64,15 @@ let CategoryPlugin = CategoryPlugin_1 = class CategoryPlugin extends components_
60
64
  onEndResolve(context) {
61
65
  const project = context.project;
62
66
  this.categorize(project);
67
+ const unusedBoosts = new Set(Object.keys(this.boosts));
68
+ for (const boost of this.usedBoosts) {
69
+ unusedBoosts.delete(boost);
70
+ }
71
+ this.usedBoosts.clear();
72
+ if (unusedBoosts.size) {
73
+ context.logger.warn(`Not all categories specified in searchCategoryBoosts were used in the documentation.` +
74
+ ` The unused categories were:\n\t${Array.from(unusedBoosts).join("\n\t")}`);
75
+ }
63
76
  }
64
77
  categorize(obj) {
65
78
  if (this.categorizeByGroup) {
@@ -76,7 +89,7 @@ let CategoryPlugin = CategoryPlugin_1 = class CategoryPlugin extends components_
76
89
  obj.groups.forEach((group) => {
77
90
  if (group.categories)
78
91
  return;
79
- group.categories = CategoryPlugin_1.getReflectionCategories(group.children, this.searchCategoryBoosts);
92
+ group.categories = this.getReflectionCategories(group.children);
80
93
  if (group.categories && group.categories.length > 1) {
81
94
  group.categories.sort(CategoryPlugin_1.sortCatCallback);
82
95
  }
@@ -91,7 +104,7 @@ let CategoryPlugin = CategoryPlugin_1 = class CategoryPlugin extends components_
91
104
  if (!obj.children || obj.children.length === 0 || obj.categories) {
92
105
  return;
93
106
  }
94
- obj.categories = CategoryPlugin_1.getReflectionCategories(obj.children, this.searchCategoryBoosts);
107
+ obj.categories = this.getReflectionCategories(obj.children);
95
108
  if (obj.categories && obj.categories.length > 1) {
96
109
  obj.categories.sort(CategoryPlugin_1.sortCatCallback);
97
110
  }
@@ -109,11 +122,11 @@ let CategoryPlugin = CategoryPlugin_1 = class CategoryPlugin extends components_
109
122
  * relevance boost to be used when searching
110
123
  * @returns An array containing all children of the given reflection categorized
111
124
  */
112
- static getReflectionCategories(reflections, categorySearchBoosts) {
125
+ getReflectionCategories(reflections) {
113
126
  const categories = [];
114
127
  let defaultCat;
115
128
  reflections.forEach((child) => {
116
- const childCategories = CategoryPlugin_1.getCategories(child);
129
+ const childCategories = this.getCategories(child);
117
130
  if (childCategories.size === 0) {
118
131
  if (!defaultCat) {
119
132
  defaultCat = categories.find((category) => category.title === CategoryPlugin_1.defaultCategory);
@@ -127,11 +140,6 @@ let CategoryPlugin = CategoryPlugin_1 = class CategoryPlugin extends components_
127
140
  }
128
141
  for (const childCat of childCategories) {
129
142
  let category = categories.find((cat) => cat.title === childCat);
130
- const catBoost = categorySearchBoosts?.[category?.title ?? -1];
131
- if (catBoost != undefined) {
132
- child.relevanceBoost =
133
- (child.relevanceBoost ?? 1) * catBoost;
134
- }
135
143
  if (category) {
136
144
  category.children.push(child);
137
145
  continue;
@@ -152,7 +160,7 @@ let CategoryPlugin = CategoryPlugin_1 = class CategoryPlugin extends components_
152
160
  * @privateRemarks
153
161
  * If you change this, also update getGroups in GroupPlugin accordingly.
154
162
  */
155
- static getCategories(reflection) {
163
+ getCategories(reflection) {
156
164
  const categories = new Set();
157
165
  function extractCategoryTags(comment) {
158
166
  if (!comment)
@@ -176,6 +184,13 @@ let CategoryPlugin = CategoryPlugin_1 = class CategoryPlugin extends components_
176
184
  }
177
185
  }
178
186
  categories.delete("");
187
+ for (const cat of categories) {
188
+ if (cat in this.boosts) {
189
+ this.usedBoosts.add(cat);
190
+ reflection.relevanceBoost =
191
+ (reflection.relevanceBoost ?? 1) * this.boosts[cat];
192
+ }
193
+ }
179
194
  return categories;
180
195
  }
181
196
  /**
@@ -220,7 +235,7 @@ __decorate([
220
235
  ], CategoryPlugin.prototype, "categorizeByGroup", void 0);
221
236
  __decorate([
222
237
  (0, utils_1.BindOption)("searchCategoryBoosts")
223
- ], CategoryPlugin.prototype, "searchCategoryBoosts", void 0);
238
+ ], CategoryPlugin.prototype, "boosts", void 0);
224
239
  CategoryPlugin = CategoryPlugin_1 = __decorate([
225
240
  (0, components_1.Component)({ name: "category" })
226
241
  ], CategoryPlugin);
@@ -196,9 +196,13 @@ let CommentPlugin = class CommentPlugin extends components_1.ConverterComponent
196
196
  * @param context The context object describing the current state the converter is in.
197
197
  * @param reflection The reflection that is currently resolved.
198
198
  */
199
- onResolve(_context, reflection) {
199
+ onResolve(context, reflection) {
200
200
  if (reflection.comment) {
201
201
  reflection.label = extractLabelTag(reflection.comment);
202
+ if (reflection.label && !/[A-Z_][A-Z0-9_]/.test(reflection.label)) {
203
+ context.logger.warn(`The label "${reflection.label}" for ${reflection.getFriendlyFullName()} cannot be referenced with a declaration reference. ` +
204
+ `Labels may only contain A-Z, 0-9, and _, and may not start with a number.`);
205
+ }
202
206
  mergeSeeTags(reflection.comment);
203
207
  }
204
208
  if (!(reflection instanceof models_1.DeclarationReflection)) {
@@ -27,6 +27,8 @@ export declare class GroupPlugin extends ConverterComponent {
27
27
  };
28
28
  /** @internal */
29
29
  sortStrategies: SortStrategy[];
30
+ boosts: Record<string, number>;
31
+ usedBoosts: Set<string>;
30
32
  /**
31
33
  * Create a new GroupPlugin instance.
32
34
  */
@@ -51,7 +53,7 @@ export declare class GroupPlugin extends ConverterComponent {
51
53
  * @privateRemarks
52
54
  * If you change this, also update getCategories in CategoryPlugin accordingly.
53
55
  */
54
- static getGroups(reflection: DeclarationReflection): Set<string>;
56
+ getGroups(reflection: DeclarationReflection): Set<string>;
55
57
  /**
56
58
  * Create a grouped representation of the given list of reflections.
57
59
  *
@@ -60,7 +62,7 @@ export declare class GroupPlugin extends ConverterComponent {
60
62
  * @param reflections The reflections that should be grouped.
61
63
  * @returns An array containing all children of the given reflection grouped by their kind.
62
64
  */
63
- static getReflectionGroups(reflections: DeclarationReflection[]): ReflectionGroup[];
65
+ getReflectionGroups(reflections: DeclarationReflection[]): ReflectionGroup[];
64
66
  /**
65
67
  * Transform the internal typescript kind identifier into a human readable version.
66
68
  *
@@ -21,6 +21,10 @@ const models_1 = require("../../models");
21
21
  * The handler sets the `groups` property of all container reflections.
22
22
  */
23
23
  let GroupPlugin = GroupPlugin_1 = class GroupPlugin extends components_1.ConverterComponent {
24
+ constructor() {
25
+ super(...arguments);
26
+ this.usedBoosts = new Set();
27
+ }
24
28
  /**
25
29
  * Create a new GroupPlugin instance.
26
30
  */
@@ -49,13 +53,23 @@ let GroupPlugin = GroupPlugin_1 = class GroupPlugin extends components_1.Convert
49
53
  */
50
54
  onEndResolve(context) {
51
55
  this.group(context.project);
56
+ const unusedBoosts = new Set(Object.keys(this.boosts));
57
+ for (const boost of this.usedBoosts) {
58
+ unusedBoosts.delete(boost);
59
+ }
60
+ this.usedBoosts.clear();
61
+ if (unusedBoosts.size &&
62
+ this.application.options.isSet("searchGroupBoosts")) {
63
+ context.logger.warn(`Not all groups specified in searchGroupBoosts were used in the documentation.` +
64
+ ` The unused groups were:\n\t${Array.from(unusedBoosts).join("\n\t")}`);
65
+ }
52
66
  }
53
67
  group(reflection) {
54
68
  if (reflection.children &&
55
69
  reflection.children.length > 0 &&
56
70
  !reflection.groups) {
57
71
  (0, sort_1.sortReflections)(reflection.children, this.sortStrategies);
58
- reflection.groups = GroupPlugin_1.getReflectionGroups(reflection.children);
72
+ reflection.groups = this.getReflectionGroups(reflection.children);
59
73
  }
60
74
  }
61
75
  /**
@@ -64,7 +78,7 @@ let GroupPlugin = GroupPlugin_1 = class GroupPlugin extends components_1.Convert
64
78
  * @privateRemarks
65
79
  * If you change this, also update getCategories in CategoryPlugin accordingly.
66
80
  */
67
- static getGroups(reflection) {
81
+ getGroups(reflection) {
68
82
  const groups = new Set();
69
83
  function extractGroupTags(comment) {
70
84
  if (!comment)
@@ -91,6 +105,13 @@ let GroupPlugin = GroupPlugin_1 = class GroupPlugin extends components_1.Convert
91
105
  if (groups.size === 0) {
92
106
  groups.add(GroupPlugin_1.getKindPlural(reflection.kind));
93
107
  }
108
+ for (const group of groups) {
109
+ if (group in this.boosts) {
110
+ this.usedBoosts.add(group);
111
+ reflection.relevanceBoost =
112
+ (reflection.relevanceBoost ?? 1) * this.boosts[group];
113
+ }
114
+ }
94
115
  return groups;
95
116
  }
96
117
  /**
@@ -101,10 +122,10 @@ let GroupPlugin = GroupPlugin_1 = class GroupPlugin extends components_1.Convert
101
122
  * @param reflections The reflections that should be grouped.
102
123
  * @returns An array containing all children of the given reflection grouped by their kind.
103
124
  */
104
- static getReflectionGroups(reflections) {
125
+ getReflectionGroups(reflections) {
105
126
  const groups = new Map();
106
127
  reflections.forEach((child) => {
107
- for (const name of GroupPlugin_1.getGroups(child)) {
128
+ for (const name of this.getGroups(child)) {
108
129
  let group = groups.get(name);
109
130
  if (!group) {
110
131
  group = new ReflectionGroup_1.ReflectionGroup(name);
@@ -175,6 +196,9 @@ GroupPlugin.PLURALS = {
175
196
  __decorate([
176
197
  (0, utils_1.BindOption)("sort")
177
198
  ], GroupPlugin.prototype, "sortStrategies", void 0);
199
+ __decorate([
200
+ (0, utils_1.BindOption)("searchGroupBoosts")
201
+ ], GroupPlugin.prototype, "boosts", void 0);
178
202
  GroupPlugin = GroupPlugin_1 = __decorate([
179
203
  (0, components_1.Component)({ name: "group" })
180
204
  ], GroupPlugin);
@@ -12,6 +12,8 @@ const components_1 = require("../components");
12
12
  const converter_1 = require("../converter");
13
13
  const utils_1 = require("../../utils");
14
14
  const array_1 = require("../../utils/array");
15
+ const declarationReference_1 = require("../comments/declarationReference");
16
+ const declarationReferenceResolver_1 = require("../comments/declarationReferenceResolver");
15
17
  /**
16
18
  * A plugin that handles `@inheritDoc` tags by copying documentation from another API item.
17
19
  * It is NOT responsible for handling bare JSDoc style `@inheritDoc` tags which do not specify
@@ -50,7 +52,11 @@ let InheritDocPlugin = class InheritDocPlugin extends components_1.ConverterComp
50
52
  const source = extractInheritDocTagReference(reflection);
51
53
  if (!source)
52
54
  continue;
53
- let sourceRefl = source && reflection.findReflectionByName(source);
55
+ const declRef = (0, declarationReference_1.parseDeclarationReference)(source, 0, source.length);
56
+ if (!declRef || /\S/.test(source.substring(declRef[1]))) {
57
+ context.logger.warn(`Declaration reference in @inheritDoc for ${reflection.getFriendlyFullName()} was not fully parsed and may resolve incorrectly.`);
58
+ }
59
+ let sourceRefl = declRef && (0, declarationReferenceResolver_1.resolveDeclarationReference)(reflection, declRef[0]);
54
60
  if (reflection instanceof models_1.SignatureReflection) {
55
61
  // Assumes that if there are overloads, they are declared in the same order as the parent.
56
62
  // TS doesn't check this, but if a user messes this up then they are almost