typedoc 0.28.6 → 0.28.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/dist/index.d.ts +1 -1
  2. package/dist/lib/converter/comments/blockLexer.d.ts +2 -1
  3. package/dist/lib/converter/comments/blockLexer.js +6 -5
  4. package/dist/lib/converter/comments/discovery.js +7 -1
  5. package/dist/lib/converter/comments/index.d.ts +20 -5
  6. package/dist/lib/converter/comments/index.js +26 -23
  7. package/dist/lib/converter/comments/lineLexer.js +1 -1
  8. package/dist/lib/converter/comments/linkResolver.d.ts +2 -2
  9. package/dist/lib/converter/comments/linkResolver.js +53 -10
  10. package/dist/lib/converter/comments/parser.d.ts +2 -2
  11. package/dist/lib/converter/comments/parser.js +6 -6
  12. package/dist/lib/converter/comments/rawLexer.js +1 -1
  13. package/dist/lib/converter/comments/textParser.js +93 -19
  14. package/dist/lib/converter/context.d.ts +10 -0
  15. package/dist/lib/converter/context.js +30 -10
  16. package/dist/lib/converter/converter.d.ts +3 -1
  17. package/dist/lib/converter/converter.js +6 -3
  18. package/dist/lib/converter/factories/signature.js +1 -2
  19. package/dist/lib/converter/factories/symbol-id.d.ts +1 -1
  20. package/dist/lib/converter/factories/symbol-id.js +2 -1
  21. package/dist/lib/converter/jsdoc.js +1 -2
  22. package/dist/lib/converter/plugins/CategoryPlugin.d.ts +3 -2
  23. package/dist/lib/converter/plugins/CategoryPlugin.js +15 -3
  24. package/dist/lib/converter/plugins/GroupPlugin.d.ts +2 -1
  25. package/dist/lib/converter/plugins/GroupPlugin.js +23 -9
  26. package/dist/lib/converter/plugins/ImplementsPlugin.js +49 -11
  27. package/dist/lib/converter/plugins/LinkResolverPlugin.d.ts +1 -2
  28. package/dist/lib/converter/plugins/LinkResolverPlugin.js +1 -55
  29. package/dist/lib/converter/types.js +2 -3
  30. package/dist/lib/converter/utils/repository.js +1 -1
  31. package/dist/lib/internationalization/internationalization.js +1 -1
  32. package/dist/lib/internationalization/locales/en.cjs +4 -1
  33. package/dist/lib/internationalization/locales/en.d.cts +4 -1
  34. package/dist/lib/models/Comment.js +1 -1
  35. package/dist/lib/models/ContainerReflection.d.ts +1 -0
  36. package/dist/lib/models/ContainerReflection.js +3 -0
  37. package/dist/lib/models/Reflection.d.ts +2 -0
  38. package/dist/lib/models/Reflection.js +3 -0
  39. package/dist/lib/output/themes/default/partials/moduleReflection.js +1 -1
  40. package/dist/lib/output/themes/default/partials/navigation.js +1 -1
  41. package/dist/lib/output/themes/default/templates/hierarchy.js +1 -1
  42. package/dist/lib/serialization/schema.d.ts +1 -1
  43. package/dist/lib/utils/options/declaration.d.ts +17 -9
  44. package/dist/lib/utils/options/declaration.js +52 -31
  45. package/dist/lib/utils/options/readers/arguments.js +2 -0
  46. package/dist/lib/utils/options/sources/typedoc.js +2 -5
  47. package/dist/lib/utils/options/tsdoc-defaults.d.ts +1 -1
  48. package/dist/lib/utils/options/tsdoc-defaults.js +1 -0
  49. package/dist/lib/utils/plugins.d.ts +2 -1
  50. package/dist/lib/utils/plugins.js +26 -17
  51. package/dist/lib/utils/sort.d.ts +2 -1
  52. package/dist/lib/utils/sort.js +4 -2
  53. package/dist/lib/utils-common/array.d.ts +1 -2
  54. package/dist/lib/utils-common/array.js +0 -7
  55. package/dist/lib/utils-common/jsx.elements.d.ts +1 -1
  56. package/dist/lib/utils-common/jsx.js +7 -6
  57. package/dist/lib/utils-common/map.d.ts +1 -1
  58. package/dist/lib/utils-common/path.d.ts +6 -0
  59. package/dist/lib/utils-common/validation.js +1 -1
  60. package/dist/lib/validation/links.js +0 -3
  61. package/package.json +12 -12
  62. package/static/style.css +2 -9
  63. package/tsdoc.json +4 -0
@@ -4,10 +4,10 @@ import { Comment, ContainerReflection, DeclarationReflection, ReferenceType, Ref
4
4
  import { isNamedNode } from "./utils/nodes.js";
5
5
  import { ConverterEvents } from "./converter-events.js";
6
6
  import { resolveAliasedSymbol } from "./utils/symbols.js";
7
- import { getComment, getFileComment, getJsDocComment, getNodeComment, getSignatureComment } from "./comments/index.js";
7
+ import { getComment, getFileComment, getJsDocComment, getNodeComment, getSignatureComment, } from "./comments/index.js";
8
8
  import { getHumanName, getQualifiedName } from "../utils/tsutils.js";
9
9
  import { findPackageForPath, normalizePath } from "#node-utils";
10
- import { createSymbolId } from "./factories/symbol-id.js";
10
+ import { createSymbolIdImpl } from "./factories/symbol-id.js";
11
11
  import { removeIf } from "#utils";
12
12
  /**
13
13
  * The context describes the current state the converter is in.
@@ -185,7 +185,7 @@ export class Context {
185
185
  * This is available on Context so that it can be monkey-patched by typedoc-plugin-missing-exports
186
186
  */
187
187
  createSymbolReference(symbol, context, name) {
188
- const ref = ReferenceType.createUnresolvedReference(name ?? symbol.name, createSymbolId(symbol), context.project, getQualifiedName(symbol, name ?? symbol.name));
188
+ const ref = ReferenceType.createUnresolvedReference(name ?? symbol.name, this.createSymbolId(symbol), context.project, getQualifiedName(symbol, name ?? symbol.name));
189
189
  ref.refersToTypeParameter = !!(symbol.flags & ts.SymbolFlags.TypeParameter);
190
190
  const symbolPath = symbol.declarations?.[0]?.getSourceFile().fileName;
191
191
  if (!symbolPath)
@@ -193,6 +193,17 @@ export class Context {
193
193
  ref.package = findPackageForPath(symbolPath)?.[0];
194
194
  return ref;
195
195
  }
196
+ /**
197
+ * Create a stable {@link ReflectionSymbolId} for the provided symbol,
198
+ * optionally targeting a specific declaration.
199
+ *
200
+ * @privateRemarks
201
+ * This is available on Context so that it can be monkey-patched by typedoc-plugin-missing-exports
202
+ * It might also turn out to be generally useful for other plugin users.
203
+ */
204
+ createSymbolId(symbol, declaration) {
205
+ return createSymbolIdImpl(symbol, declaration);
206
+ }
196
207
  addChild(reflection) {
197
208
  if (this.scope instanceof ContainerReflection) {
198
209
  this.scope.addChild(reflection);
@@ -211,7 +222,7 @@ export class Context {
211
222
  registerReflection(reflection, symbol, filePath) {
212
223
  if (symbol) {
213
224
  this.reflectionIdToSymbolMap.set(reflection.id, symbol);
214
- const id = createSymbolId(symbol);
225
+ const id = this.createSymbolId(symbol);
215
226
  // #2466
216
227
  // If we just registered a member of a class or interface, then we need to check if
217
228
  // we've registered this symbol before under the wrong parent reflection.
@@ -237,7 +248,7 @@ export class Context {
237
248
  }
238
249
  }
239
250
  getReflectionFromSymbol(symbol) {
240
- return this.project.getReflectionFromSymbolId(createSymbolId(symbol));
251
+ return this.project.getReflectionFromSymbolId(this.createSymbolId(symbol));
241
252
  }
242
253
  getSymbolFromReflection(reflection) {
243
254
  return this.reflectionIdToSymbolMap.get(reflection.id);
@@ -246,20 +257,29 @@ export class Context {
246
257
  setActiveProgram(program) {
247
258
  this._program = program;
248
259
  }
260
+ createCommentContext() {
261
+ return {
262
+ config: this.converter.config,
263
+ logger: this.logger,
264
+ checker: this.checker,
265
+ files: this.project.files,
266
+ createSymbolId: (s, d) => this.createSymbolId(s, d),
267
+ };
268
+ }
249
269
  getComment(symbol, kind) {
250
- return getComment(symbol, kind, this.converter.config, this.logger, this.checker, this.project.files);
270
+ return getComment(symbol, kind, this.createCommentContext());
251
271
  }
252
272
  getNodeComment(node, moduleComment) {
253
- return getNodeComment(node, moduleComment, this.converter.config, this.logger, this.checker, this.project.files);
273
+ return getNodeComment(node, moduleComment, this.createCommentContext());
254
274
  }
255
275
  getFileComment(node) {
256
- return getFileComment(node, this.converter.config, this.logger, this.checker, this.project.files);
276
+ return getFileComment(node, this.createCommentContext());
257
277
  }
258
278
  getJsDocComment(declaration) {
259
- return getJsDocComment(declaration, this.converter.config, this.logger, this.checker, this.project.files);
279
+ return getJsDocComment(declaration, this.createCommentContext());
260
280
  }
261
281
  getSignatureComment(declaration) {
262
- return getSignatureComment(declaration, this.converter.config, this.logger, this.checker, this.project.files);
282
+ return getSignatureComment(declaration, this.createCommentContext());
263
283
  }
264
284
  shouldInline(symbol, name) {
265
285
  if (this.preventInline.has(name))
@@ -1,6 +1,6 @@
1
1
  import ts from "typescript";
2
2
  import type { Application } from "../application.js";
3
- import { Comment, type CommentDisplayPart, type ContainerReflection, type DeclarationReflection, DocumentReflection, type ParameterReflection, ProjectReflection, type Reflection, type ReflectionSymbolId, type SignatureReflection, type SomeType, type TypeParameterReflection } from "../models/index.js";
3
+ import { Comment, type CommentDisplayPart, type ContainerReflection, type DeclarationReflection, DocumentReflection, type ParameterReflection, ProjectReflection, Reflection, type ReflectionSymbolId, type SignatureReflection, type SomeType, type TypeParameterReflection } from "../models/index.js";
4
4
  import { Context } from "./context.js";
5
5
  import { AbstractComponent } from "../utils/component.js";
6
6
  import { type GlobString, MinimalSourceFile } from "#utils";
@@ -187,6 +187,8 @@ export declare class Converter extends AbstractComponent<Application, ConverterE
187
187
  addUnknownSymbolResolver(resolver: ExternalSymbolResolver): void;
188
188
  /** @internal */
189
189
  resolveExternalLink(ref: DeclarationReference, refl: Reflection, part: CommentDisplayPart | undefined, symbolId: ReflectionSymbolId | undefined): ExternalResolveResult | string | undefined;
190
+ resolveLinks(reflection: Reflection): void;
191
+ /** @deprecated just pass the reflection */
190
192
  resolveLinks(comment: Comment, owner: Reflection): void;
191
193
  resolveLinks(parts: readonly CommentDisplayPart[], owner: Reflection): CommentDisplayPart[];
192
194
  /**
@@ -34,7 +34,7 @@ var __runInitializers = (this && this.__runInitializers) || function (thisArg, i
34
34
  };
35
35
  import ts from "typescript";
36
36
  import { ok } from "assert";
37
- import { Comment, DocumentReflection, ProjectReflection, ReflectionKind, } from "../models/index.js";
37
+ import { Comment, DocumentReflection, ProjectReflection, Reflection, ReflectionKind, } from "../models/index.js";
38
38
  import { Context } from "./context.js";
39
39
  import { AbstractComponent } from "../utils/component.js";
40
40
  import { getDocumentEntryPoints, Option, readFile } from "../utils/index.js";
@@ -374,8 +374,11 @@ let Converter = (() => {
374
374
  }
375
375
  }
376
376
  resolveLinks(comment, owner) {
377
- if (comment instanceof Comment) {
378
- resolveLinks(comment, owner, (ref, part, refl, id) => this.resolveExternalLink(ref, part, refl, id), { preserveLinkText: this.preserveLinkText });
377
+ if (comment instanceof Reflection) {
378
+ resolveLinks(comment, (ref, part, refl, id) => this.resolveExternalLink(ref, part, refl, id), { preserveLinkText: this.preserveLinkText });
379
+ }
380
+ else if (comment instanceof Comment) {
381
+ resolveLinks(owner, (ref, part, refl, id) => this.resolveExternalLink(ref, part, refl, id), { preserveLinkText: this.preserveLinkText });
379
382
  }
380
383
  else {
381
384
  return resolvePartLinks(owner, comment, (ref, part, refl, id) => this.resolveExternalLink(ref, part, refl, id), { preserveLinkText: this.preserveLinkText });
@@ -4,7 +4,6 @@ import { DeclarationReflection, IntrinsicType, ParameterReflection, PredicateTyp
4
4
  import { ConverterEvents } from "../converter-events.js";
5
5
  import { convertDefaultValue } from "../convert-expression.js";
6
6
  import { removeUndefined } from "../utils/reflections.js";
7
- import { createSymbolId } from "./symbol-id.js";
8
7
  export function createSignature(context, kind, signature, symbol, declaration) {
9
8
  assert(context.scope instanceof DeclarationReflection);
10
9
  declaration ||= signature.getDeclaration();
@@ -17,7 +16,7 @@ export function createSignature(context, kind, signature, symbol, declaration) {
17
16
  sigRef.setFlag(ReflectionFlag.Static);
18
17
  }
19
18
  if (symbol && declaration) {
20
- context.project.registerSymbolId(sigRef, createSymbolId(symbol, declaration));
19
+ context.project.registerSymbolId(sigRef, context.createSymbolId(symbol, declaration));
21
20
  }
22
21
  let parentReflection = context.scope;
23
22
  if (parentReflection.kindOf(ReflectionKind.TypeLiteral) &&
@@ -1,4 +1,4 @@
1
1
  import { ReflectionSymbolId } from "#models";
2
2
  import ts from "typescript";
3
- export declare function createSymbolId(symbol: ts.Symbol, declaration?: ts.Declaration): ReflectionSymbolId;
3
+ export declare function createSymbolIdImpl(symbol: ts.Symbol, declaration?: ts.Declaration): ReflectionSymbolId;
4
4
  export declare function addInferredDeclarationMapPaths(opts: ts.CompilerOptions, files: readonly string[]): void;
@@ -7,7 +7,8 @@ import ts from "typescript";
7
7
  const declarationMapCache = new Map();
8
8
  let transientCount = 0;
9
9
  const transientIds = new WeakMap();
10
- export function createSymbolId(symbol, declaration) {
10
+ // Don't use this directly, use Context.createSymbolId instead.
11
+ export function createSymbolIdImpl(symbol, declaration) {
11
12
  declaration ??= symbol.declarations?.[0];
12
13
  const tsSource = declaration?.getSourceFile().fileName ?? "";
13
14
  const sourceFileName = resolveDeclarationMaps(tsSource);
@@ -6,7 +6,6 @@ import ts from "typescript";
6
6
  import { DeclarationReflection, IntrinsicType, ReflectionKind, ReflectionType, SignatureReflection, } from "../models/index.js";
7
7
  import { ConverterEvents } from "./converter-events.js";
8
8
  import { convertParameterNodes, convertTemplateParameterNodes } from "./factories/signature.js";
9
- import { createSymbolId } from "./factories/symbol-id.js";
10
9
  export function convertJsDocAlias(context, symbol, declaration, exportSymbol) {
11
10
  if (declaration.typeExpression &&
12
11
  ts.isJSDocTypeLiteral(declaration.typeExpression)) {
@@ -57,7 +56,7 @@ function convertJsDocSignature(context, node) {
57
56
  context.registerReflection(reflection, symbol);
58
57
  context.converter.trigger(ConverterEvents.CREATE_DECLARATION, context, reflection);
59
58
  const signature = new SignatureReflection("__type", ReflectionKind.CallSignature, reflection);
60
- context.project.registerSymbolId(signature, createSymbolId(symbol, node));
59
+ context.project.registerSymbolId(signature, context.createSymbolId(symbol, node));
61
60
  context.registerReflection(signature, void 0);
62
61
  const signatureCtx = rc.withScope(signature);
63
62
  reflection.signatures = [signature];
@@ -1,4 +1,4 @@
1
- import { type DeclarationReflection, type DocumentReflection } from "../../models/index.js";
1
+ import { ContainerReflection, type DeclarationReflection, type DocumentReflection } from "../../models/index.js";
2
2
  import { ConverterComponent } from "../components.js";
3
3
  import type { Converter } from "../converter.js";
4
4
  /**
@@ -7,7 +7,7 @@ import type { Converter } from "../converter.js";
7
7
  * The handler sets the ´category´ property of all reflections.
8
8
  */
9
9
  export declare class CategoryPlugin extends ConverterComponent {
10
- sortFunction: (reflections: Array<DeclarationReflection | DocumentReflection>) => void;
10
+ defaultSortFunction: (reflections: Array<DeclarationReflection | DocumentReflection>) => void;
11
11
  accessor defaultCategory: string;
12
12
  accessor categoryOrder: string[];
13
13
  accessor categorizeByGroup: boolean;
@@ -35,6 +35,7 @@ export declare class CategoryPlugin extends ConverterComponent {
35
35
  * @returns An array containing all children of the given reflection categorized
36
36
  */
37
37
  private getReflectionCategories;
38
+ getSortFunction(reflection: ContainerReflection): (reflections: (DeclarationReflection | DocumentReflection)[]) => void;
38
39
  /**
39
40
  * Callback used to sort categories by name.
40
41
  *
@@ -39,6 +39,7 @@ import { getSortFunction, Option } from "../../utils/index.js";
39
39
  import { ConverterComponent } from "../components.js";
40
40
  import { ConverterEvents } from "../converter-events.js";
41
41
  import { i18n } from "#utils";
42
+ import { isValidSortStrategy } from "../../utils/sort.js";
42
43
  /**
43
44
  * A handler that sorts and categorizes the found reflections in the resolving phase.
44
45
  *
@@ -66,7 +67,7 @@ let CategoryPlugin = (() => {
66
67
  __esDecorate(this, null, _categorizeByGroup_decorators, { kind: "accessor", name: "categorizeByGroup", static: false, private: false, access: { has: obj => "categorizeByGroup" in obj, get: obj => obj.categorizeByGroup, set: (obj, value) => { obj.categorizeByGroup = value; } }, metadata: _metadata }, _categorizeByGroup_initializers, _categorizeByGroup_extraInitializers);
67
68
  if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
68
69
  }
69
- sortFunction;
70
+ defaultSortFunction;
70
71
  #defaultCategory_accessor_storage = __runInitializers(this, _defaultCategory_initializers, void 0);
71
72
  get defaultCategory() { return this.#defaultCategory_accessor_storage; }
72
73
  set defaultCategory(value) { this.#defaultCategory_accessor_storage = value; }
@@ -97,7 +98,7 @@ let CategoryPlugin = (() => {
97
98
  * Triggered when the converter begins converting a project.
98
99
  */
99
100
  setup() {
100
- this.sortFunction = getSortFunction(this.application.options);
101
+ this.defaultSortFunction = getSortFunction(this.application.options);
101
102
  // Set up static properties
102
103
  if (this.defaultCategory) {
103
104
  CategoryPlugin.defaultCategory = this.defaultCategory;
@@ -201,10 +202,21 @@ let CategoryPlugin = (() => {
201
202
  }
202
203
  }
203
204
  for (const cat of categories.values()) {
204
- this.sortFunction(cat.children);
205
+ this.getSortFunction(parent)(cat.children);
205
206
  }
206
207
  return Array.from(categories.values());
207
208
  }
209
+ getSortFunction(reflection) {
210
+ const tag = reflection.comment?.getTag("@sortStrategy");
211
+ if (tag) {
212
+ const text = Comment.combineDisplayParts(tag.content);
213
+ // We don't need to warn about invalid strategies here because the group plugin
214
+ // runs first and will have already warned.
215
+ const strategies = text.split(/[,\s]+/).filter(isValidSortStrategy);
216
+ return getSortFunction(this.application.options, strategies);
217
+ }
218
+ return this.defaultSortFunction;
219
+ }
208
220
  /**
209
221
  * Callback used to sort categories by name.
210
222
  *
@@ -8,7 +8,7 @@ import type { Converter } from "../converter.js";
8
8
  * The handler sets the `groups` property of all container reflections.
9
9
  */
10
10
  export declare class GroupPlugin extends ConverterComponent {
11
- sortFunction: (reflections: Array<DeclarationReflection | DocumentReflection>) => void;
11
+ defaultSortFunction: (reflections: Array<DeclarationReflection | DocumentReflection>) => void;
12
12
  accessor groupOrder: string[];
13
13
  accessor sortEntryPoints: boolean;
14
14
  accessor groupReferencesByType: boolean;
@@ -40,6 +40,7 @@ export declare class GroupPlugin extends ConverterComponent {
40
40
  * @returns An array containing all children of the given reflection grouped by their kind.
41
41
  */
42
42
  getReflectionGroups(parent: ContainerReflection, reflections: Array<DeclarationReflection | DocumentReflection>): ReflectionGroup[];
43
+ getSortFunction(reflection: ContainerReflection): (reflections: Array<DeclarationReflection | DocumentReflection>) => void;
43
44
  /**
44
45
  * Callback used to sort groups by name.
45
46
  */
@@ -35,13 +35,13 @@ var __runInitializers = (this && this.__runInitializers) || function (thisArg, i
35
35
  import { ContainerReflection, ReferenceReflection, ReflectionKind, } from "../../models/index.js";
36
36
  import { ReflectionGroup } from "../../models/ReflectionGroup.js";
37
37
  import { ConverterComponent } from "../components.js";
38
- import { getSortFunction } from "../../utils/sort.js";
38
+ import { getSortFunction, isValidSortStrategy, SORT_STRATEGIES } from "../../utils/sort.js";
39
39
  import { Option } from "../../utils/index.js";
40
40
  import { Comment } from "../../models/index.js";
41
41
  import { ConverterEvents } from "../converter-events.js";
42
42
  import { ApplicationEvents } from "../../application-events.js";
43
43
  import assert from "assert";
44
- import { i18n } from "#utils";
44
+ import { i18n, partition } from "#utils";
45
45
  // Same as the defaultKindSortOrder in sort.ts
46
46
  const defaultGroupOrder = [
47
47
  ReflectionKind.Document,
@@ -89,7 +89,7 @@ let GroupPlugin = (() => {
89
89
  __esDecorate(this, null, _groupReferencesByType_decorators, { kind: "accessor", name: "groupReferencesByType", static: false, private: false, access: { has: obj => "groupReferencesByType" in obj, get: obj => obj.groupReferencesByType, set: (obj, value) => { obj.groupReferencesByType = value; } }, metadata: _metadata }, _groupReferencesByType_initializers, _groupReferencesByType_extraInitializers);
90
90
  if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
91
91
  }
92
- sortFunction;
92
+ defaultSortFunction;
93
93
  #groupOrder_accessor_storage = __runInitializers(this, _groupOrder_initializers, void 0);
94
94
  get groupOrder() { return this.#groupOrder_accessor_storage; }
95
95
  set groupOrder(value) { this.#groupOrder_accessor_storage = value; }
@@ -130,25 +130,26 @@ let GroupPlugin = (() => {
130
130
  }
131
131
  }
132
132
  setup() {
133
- this.sortFunction = getSortFunction(this.application.options);
133
+ this.defaultSortFunction = getSortFunction(this.application.options);
134
134
  GroupPlugin.WEIGHTS = this.groupOrder;
135
135
  if (GroupPlugin.WEIGHTS.length === 0) {
136
136
  GroupPlugin.WEIGHTS = defaultGroupOrder.map((kind) => ReflectionKind.pluralString(kind));
137
137
  }
138
138
  }
139
139
  group(reflection) {
140
+ const sortFunction = this.getSortFunction(reflection);
140
141
  if (reflection.childrenIncludingDocuments && !reflection.groups) {
141
142
  if (reflection.children) {
142
143
  if (this.sortEntryPoints ||
143
144
  !reflection.children.some((c) => c.kindOf(ReflectionKind.Module))) {
144
- this.sortFunction(reflection.children);
145
- this.sortFunction(reflection.documents || []);
146
- this.sortFunction(reflection.childrenIncludingDocuments);
145
+ sortFunction(reflection.children);
146
+ sortFunction(reflection.documents || []);
147
+ sortFunction(reflection.childrenIncludingDocuments);
147
148
  }
148
149
  }
149
150
  else if (reflection.documents) {
150
- this.sortFunction(reflection.documents);
151
- this.sortFunction(reflection.childrenIncludingDocuments);
151
+ sortFunction(reflection.documents);
152
+ sortFunction(reflection.childrenIncludingDocuments);
152
153
  }
153
154
  if (reflection.comment?.hasModifier("@disableGroups")) {
154
155
  return;
@@ -239,6 +240,19 @@ let GroupPlugin = (() => {
239
240
  }
240
241
  return Array.from(groups.values()).sort(GroupPlugin.sortGroupCallback);
241
242
  }
243
+ getSortFunction(reflection) {
244
+ const tag = reflection.comment?.getTag("@sortStrategy");
245
+ if (tag) {
246
+ const text = Comment.combineDisplayParts(tag.content);
247
+ const strategies = text.split(/[,\s]+/);
248
+ const [valid, invalid] = partition(strategies, isValidSortStrategy);
249
+ for (const inv of invalid) {
250
+ this.application.logger.warn(i18n.comment_for_0_specifies_1_as_sort_strategy_but_only_2_is_valid(reflection.getFriendlyFullName(), inv, SORT_STRATEGIES.join("\n\t")));
251
+ }
252
+ return getSortFunction(this.application.options, valid);
253
+ }
254
+ return this.defaultSortFunction;
255
+ }
242
256
  /**
243
257
  * Callback used to sort groups by name.
244
258
  */
@@ -58,7 +58,9 @@ export class ImplementsPlugin extends ConverterComponent {
58
58
  });
59
59
  }
60
60
  analyzeInheritance(project, reflection) {
61
- const extendedTypes = filterMap(reflection.extendedTypes ?? [], (type) => {
61
+ if (!reflection.extendedTypes)
62
+ return;
63
+ const extendedTypes = filterMap(reflection.extendedTypes, (type) => {
62
64
  return type instanceof ReferenceType &&
63
65
  type.reflection instanceof DeclarationReflection
64
66
  ? type
@@ -73,13 +75,42 @@ export class ImplementsPlugin extends ConverterComponent {
73
75
  ? "overwrites"
74
76
  : "inheritedFrom";
75
77
  for (const [childSig, parentSig] of zip(child.signatures ?? [], parentMember.signatures ?? [])) {
76
- childSig[key] = ReferenceType.createResolvedReference(`${parent.name}.${parentMember.name}`, parentSig, project);
78
+ // If we're already pointing at something because TS said we should reference
79
+ // it, then don't overwrite the reference.
80
+ if (!childSig[key]?.reflection) {
81
+ childSig[key] = ReferenceType.createResolvedReference(`${parent.name}.${parentMember.name}`, parentSig, project);
82
+ }
83
+ }
84
+ if (!child[key]?.reflection) {
85
+ child[key] = ReferenceType.createResolvedReference(`${parent.name}.${parentMember.name}`, parentMember, project);
77
86
  }
78
- child[key] = ReferenceType.createResolvedReference(`${parent.name}.${parentMember.name}`, parentMember, project);
79
87
  this.handleInheritedComments(child, parentMember);
80
88
  }
81
89
  }
82
90
  }
91
+ // #2978, this is very unfortunate. If a child's parent links are broken at this point,
92
+ // we replace them with an intentionally broken link so that they won't ever be resolved.
93
+ // This is done because if we don't do it then we run into issues where we have a link which
94
+ // points to some ReflectionSymbolId which might not exist now, but once we've gone through
95
+ // serialization/deserialization, might point to an unexpected location. (See the mixin
96
+ // converter tests, I suspect this might actually be an indication of something else slightly
97
+ // broken there, but don't want to spend more time with this right now.)
98
+ for (const child of reflection.children || []) {
99
+ if (child.inheritedFrom && !child.inheritedFrom.reflection) {
100
+ child.inheritedFrom = ReferenceType.createBrokenReference(child.inheritedFrom.name, project);
101
+ }
102
+ if (child.overwrites && !child.overwrites.reflection) {
103
+ child.overwrites = ReferenceType.createBrokenReference(child.overwrites.name, project);
104
+ }
105
+ for (const childSig of child.getAllSignatures()) {
106
+ if (childSig.inheritedFrom && !childSig.inheritedFrom.reflection) {
107
+ childSig.inheritedFrom = ReferenceType.createBrokenReference(childSig.inheritedFrom.name, project);
108
+ }
109
+ if (childSig.overwrites && !childSig.overwrites.reflection) {
110
+ childSig.overwrites = ReferenceType.createBrokenReference(childSig.overwrites.name, project);
111
+ }
112
+ }
113
+ }
83
114
  }
84
115
  onResolveEnd(context) {
85
116
  this.resolve(context.project);
@@ -310,8 +341,19 @@ function findProperty(reflection, parent) {
310
341
  });
311
342
  }
312
343
  function createLink(context, reflection, clause, expr, symbol, isInherit) {
313
- const project = context.project;
314
344
  const name = `${expr.expression.getText()}.${getHumanName(symbol.name)}`;
345
+ // We should always have rootSymbols, but check just in case. We use the first
346
+ // symbol here as TypeDoc's models don't have multiple symbols for the parent
347
+ // reference. This is technically wrong because symbols might be declared in
348
+ // multiple locations (interface declaration merging), but that's an uncommon
349
+ // enough use case that it doesn't seem worthwhile to complicate the rest of the
350
+ // world to deal with it.
351
+ // Note that we also need to check that the root symbol isn't this symbol.
352
+ // This seems to happen sometimes when dealing with interface inheritance.
353
+ const rootSymbols = context.checker.getRootSymbols(symbol);
354
+ const ref = rootSymbols.length && rootSymbols[0] != symbol
355
+ ? context.createSymbolReference(rootSymbols[0], context, name)
356
+ : ReferenceType.createBrokenReference(name, context.project);
315
357
  link(reflection);
316
358
  link(reflection.getSignature);
317
359
  link(reflection.setSignature);
@@ -321,23 +363,19 @@ function createLink(context, reflection, clause, expr, symbol, isInherit) {
321
363
  for (const sig of reflection.signatures ?? []) {
322
364
  link(sig);
323
365
  }
324
- // Intentionally create broken links here. These will be replaced with real links during
325
- // resolution if we can do so. We create broken links rather than real links because in the
326
- // case of an inherited symbol, we'll end up referencing a single symbol ID rather than one
327
- // for each class.
328
366
  function link(target) {
329
367
  if (!target)
330
368
  return;
331
369
  if (clause.token === ts.SyntaxKind.ImplementsKeyword) {
332
- target.implementationOf ??= ReferenceType.createBrokenReference(name, project);
370
+ target.implementationOf ??= ref;
333
371
  return;
334
372
  }
335
373
  if (isInherit) {
336
374
  target.setFlag(ReflectionFlag.Inherited);
337
- target.inheritedFrom ??= ReferenceType.createBrokenReference(name, project);
375
+ target.inheritedFrom ??= ref;
338
376
  }
339
377
  else {
340
- target.overwrites ??= ReferenceType.createBrokenReference(name, project);
378
+ target.overwrites ??= ref;
341
379
  }
342
380
  }
343
381
  }
@@ -1,7 +1,7 @@
1
1
  import { ConverterComponent } from "../components.js";
2
2
  import type { Context, Converter } from "../../converter/index.js";
3
3
  import { type ValidationOptions } from "../../utils/index.js";
4
- import { type ProjectReflection } from "../../models/index.js";
4
+ import type { ProjectReflection } from "../../models/index.js";
5
5
  /**
6
6
  * A plugin that resolves `{@link Foo}` tags.
7
7
  */
@@ -10,5 +10,4 @@ export declare class LinkResolverPlugin extends ConverterComponent {
10
10
  constructor(owner: Converter);
11
11
  onResolve(context: Context): void;
12
12
  resolveLinks(project: ProjectReflection): void;
13
- private resolveCategoryLinks;
14
13
  }
@@ -35,7 +35,6 @@ var __runInitializers = (this && this.__runInitializers) || function (thisArg, i
35
35
  import { ConverterComponent } from "../components.js";
36
36
  import { ConverterEvents } from "../converter-events.js";
37
37
  import { Option } from "../../utils/index.js";
38
- import { ContainerReflection, makeRecursiveVisitor, } from "../../models/index.js";
39
38
  import { discoverAllReferenceTypes } from "../../utils/reflections.js";
40
39
  import { ApplicationEvents } from "../../application-events.js";
41
40
  /**
@@ -68,55 +67,7 @@ let LinkResolverPlugin = (() => {
68
67
  resolveLinks(project) {
69
68
  for (const id in project.reflections) {
70
69
  const reflection = project.reflections[id];
71
- if (reflection.comment) {
72
- this.owner.resolveLinks(reflection.comment, reflection);
73
- }
74
- if (reflection.isDeclaration()) {
75
- reflection.type?.visit(makeRecursiveVisitor({
76
- union: (type) => {
77
- type.elementSummaries = type.elementSummaries?.map((parts) => this.owner.resolveLinks(parts, reflection));
78
- },
79
- }));
80
- if (reflection.readme) {
81
- reflection.readme = this.owner.resolveLinks(reflection.readme, reflection);
82
- }
83
- }
84
- if (reflection.isDocument()) {
85
- reflection.content = this.owner.resolveLinks(reflection.content, reflection);
86
- }
87
- if (reflection.isParameter() &&
88
- reflection.type?.type === "reference" &&
89
- reflection.type.highlightedProperties) {
90
- const resolved = new Map(Array.from(reflection.type.highlightedProperties, ([name, parts]) => {
91
- return [
92
- name,
93
- this.owner.resolveLinks(parts, reflection),
94
- ];
95
- }));
96
- reflection.type.highlightedProperties = resolved;
97
- }
98
- if (reflection instanceof ContainerReflection) {
99
- if (reflection.groups) {
100
- for (const group of reflection.groups) {
101
- if (group.description) {
102
- group.description = this.owner.resolveLinks(group.description, reflection);
103
- }
104
- if (group.categories) {
105
- for (const cat of group.categories) {
106
- this.resolveCategoryLinks(cat, reflection);
107
- }
108
- }
109
- }
110
- }
111
- if (reflection.categories) {
112
- for (const cat of reflection.categories) {
113
- this.resolveCategoryLinks(cat, reflection);
114
- }
115
- }
116
- }
117
- }
118
- if (project.readme) {
119
- project.readme = this.owner.resolveLinks(project.readme, project);
70
+ this.owner.resolveLinks(reflection);
120
71
  }
121
72
  for (const { type, owner } of discoverAllReferenceTypes(project, false)) {
122
73
  if (!type.reflection) {
@@ -132,11 +83,6 @@ let LinkResolverPlugin = (() => {
132
83
  }
133
84
  }
134
85
  }
135
- resolveCategoryLinks(category, owner) {
136
- if (category.description) {
137
- category.description = this.owner.resolveLinks(category.description, owner);
138
- }
139
- }
140
86
  };
141
87
  })();
142
88
  export { LinkResolverPlugin };
@@ -8,7 +8,6 @@ import { convertParameterNodes, convertTypeParameterNodes, createSignature } fro
8
8
  import { convertSymbol } from "./symbols.js";
9
9
  import { isObjectType, isTypeReference } from "./utils/nodes.js";
10
10
  import { removeUndefined } from "./utils/reflections.js";
11
- import { createSymbolId } from "./factories/symbol-id.js";
12
11
  const converters = new Map();
13
12
  export function loadConverters() {
14
13
  if (converters.size)
@@ -159,7 +158,7 @@ const constructorConverter = {
159
158
  if (node.modifiers?.some((m) => m.kind === ts.SyntaxKind.AbstractKeyword)) {
160
159
  signature.setFlag(ReflectionFlag.Abstract);
161
160
  }
162
- context.project.registerSymbolId(signature, createSymbolId(symbol, node));
161
+ context.project.registerSymbolId(signature, context.createSymbolId(symbol, node));
163
162
  context.registerReflection(signature, void 0);
164
163
  const signatureCtx = rc.withScope(signature);
165
164
  reflection.signatures = [signature];
@@ -208,7 +207,7 @@ const functionTypeConverter = {
208
207
  context.registerReflection(reflection, symbol);
209
208
  context.converter.trigger(ConverterEvents.CREATE_DECLARATION, context, reflection);
210
209
  const signature = new SignatureReflection("__type", ReflectionKind.CallSignature, reflection);
211
- context.project.registerSymbolId(signature, createSymbolId(symbol, node));
210
+ context.project.registerSymbolId(signature, context.createSymbolId(symbol, node));
212
211
  context.registerReflection(signature, undefined);
213
212
  const signatureCtx = rc.withScope(signature);
214
213
  reflection.signatures = [signature];
@@ -140,7 +140,7 @@ let GitRepository = (() => {
140
140
  */
141
141
  static tryCreateRepository(path, sourceLinkTemplate, gitRevision, gitRemote, logger) {
142
142
  gitRevision ||= git("-C", path, "rev-parse", "HEAD").stdout.trim();
143
- if (!gitRevision)
143
+ if (gitRevision == "HEAD")
144
144
  return; // Will only happen in a repo with no commits.
145
145
  let urlTemplate;
146
146
  if (sourceLinkTemplate) {
@@ -16,7 +16,7 @@ export function loadTranslations(lang) {
16
16
  return req(`./locales/${lang}.cjs`);
17
17
  }
18
18
  catch {
19
- return {};
19
+ return loadTranslations("en");
20
20
  }
21
21
  }
22
22
  /**
@@ -72,6 +72,7 @@ module.exports = {
72
72
  not_all_search_group_boosts_used_0: `Not all groups specified in searchGroupBoosts were used in the documentation. The unused groups were:\n\t{0}`,
73
73
  comment_for_0_includes_categoryDescription_for_1_but_no_child_in_group: `Comment for {0} includes @categoryDescription for "{1}", but no child is placed in that category`,
74
74
  comment_for_0_includes_groupDescription_for_1_but_no_child_in_group: `Comment for {0} includes @groupDescription for "{1}", but no child is placed in that group`,
75
+ comment_for_0_specifies_1_as_sort_strategy_but_only_2_is_valid: `Comment for {0} specifies @sortStrategy with "{1}", which is an invalid sort strategy, the following are valid:\n\t{2}`,
75
76
  label_0_for_1_cannot_be_referenced: `The label "{0}" for {1} cannot be referenced with a declaration reference. Labels may only contain A-Z, 0-9, and _, and may not start with a number`,
76
77
  modifier_tag_0_is_mutually_exclusive_with_1_in_comment_for_2: `The modifier tag {0} is mutually exclusive with {1} in the comment for {2}`,
77
78
  signature_0_has_unused_param_with_name_1: `The signature {0} has an @param with name "{1}", which was not used`,
@@ -274,13 +275,15 @@ module.exports = {
274
275
  useHostedBaseUrlForAbsoluteLinks_requires_hostedBaseUrl: "The useHostedBaseUrlForAbsoluteLinks option requires that hostedBaseUrl be set",
275
276
  favicon_must_have_one_of_the_following_extensions_0: "Favicon must have one of the following extensions: {0}",
276
277
  option_0_must_be_an_object: "The '{0}' option must be a non-array object",
278
+ option_0_must_be_an_array_of_string: "The '{0}' option must be set to an array of strings",
279
+ option_0_must_be_an_array_of_string_or_functions: "The '{0}' option must be set to an array of strings/functions",
277
280
  option_0_must_be_a_function: "The '{0}' option must be a function",
278
281
  option_0_must_be_object_with_urls: `{0} must be an object with string labels as keys and URL values`,
279
282
  visibility_filters_only_include_0: `visibilityFilters can only include the following non-@ keys: {0}`,
280
283
  visibility_filters_must_be_booleans: `All values of visibilityFilters must be booleans`,
281
284
  option_0_values_must_be_numbers: "All values of {0} must be numbers",
282
285
  option_0_values_must_be_array_of_tags: "{0} must be an array of valid tag names",
283
- option_0_specified_1_but_only_2_is_valid: `{0} may only specify known values, and invalid values were provided ({1}). The valid sort strategies are:\n{2}`,
286
+ option_0_specified_1_but_only_2_is_valid: `{0} may only specify known values, and invalid values were provided ({1}). The valid options are:\n{2}`,
284
287
  option_outputs_must_be_array: `"outputs" option must be an array of { name: string, path: string, options?: TypeDocOptions } values.`,
285
288
  specified_output_0_has_not_been_defined: `Specified output "{0}" has not been defined.`,
286
289
  // https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax#alerts