typedoc 0.27.3 → 0.27.5

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 (46) hide show
  1. package/README.md +0 -3
  2. package/dist/index.d.ts +5 -0
  3. package/dist/index.js +5 -0
  4. package/dist/lib/converter/comments/blockLexer.js +28 -10
  5. package/dist/lib/converter/comments/declarationReferenceResolver.js +12 -6
  6. package/dist/lib/converter/comments/lineLexer.js +23 -7
  7. package/dist/lib/converter/comments/linkResolver.js +9 -4
  8. package/dist/lib/converter/comments/rawLexer.js +28 -16
  9. package/dist/lib/converter/comments/textParser.js +1 -0
  10. package/dist/lib/converter/converter-events.d.ts +1 -0
  11. package/dist/lib/converter/converter-events.js +1 -0
  12. package/dist/lib/converter/converter.d.ts +14 -0
  13. package/dist/lib/converter/converter.js +17 -0
  14. package/dist/lib/converter/plugins/CommentPlugin.js +3 -2
  15. package/dist/lib/converter/plugins/IncludePlugin.js +1 -0
  16. package/dist/lib/debug/debugReflectionLifetimes.d.ts +2 -0
  17. package/dist/lib/debug/debugReflectionLifetimes.js +19 -0
  18. package/dist/lib/debug/debugRendererUrls.d.ts +5 -0
  19. package/dist/lib/debug/debugRendererUrls.js +59 -0
  20. package/dist/lib/debug/index.d.ts +2 -0
  21. package/dist/lib/debug/index.js +2 -0
  22. package/dist/lib/internationalization/internationalization.d.ts +1 -2
  23. package/dist/lib/internationalization/locales/en.cjs +1 -0
  24. package/dist/lib/internationalization/locales/en.d.cts +1 -0
  25. package/dist/lib/models/ReflectionCategory.js +1 -1
  26. package/dist/lib/models/ReflectionGroup.js +1 -1
  27. package/dist/lib/models/reflections/project.js +1 -0
  28. package/dist/lib/models/types.js +9 -2
  29. package/dist/lib/output/components.d.ts +1 -1
  30. package/dist/lib/output/themes/MarkedPlugin.d.ts +2 -0
  31. package/dist/lib/output/themes/MarkedPlugin.js +33 -7
  32. package/dist/lib/output/themes/default/DefaultTheme.js +14 -1
  33. package/dist/lib/output/themes/default/partials/comment.js +3 -0
  34. package/dist/lib/output/themes/default/partials/member.signatures.js +1 -1
  35. package/dist/lib/output/themes/default/partials/navigation.js +1 -1
  36. package/dist/lib/output/themes/default/partials/typeDetails.js +14 -4
  37. package/dist/lib/serialization/serializer.d.ts +1 -0
  38. package/dist/lib/serialization/serializer.js +4 -1
  39. package/dist/lib/utils/compress.d.ts +2 -2
  40. package/dist/lib/utils/compress.js +5 -5
  41. package/dist/lib/utils/jsx.d.ts +2 -2
  42. package/dist/lib/utils/jsx.elements.d.ts +11 -0
  43. package/dist/lib/utils/options/declaration.d.ts +4 -0
  44. package/dist/lib/utils/options/sources/typedoc.js +1 -0
  45. package/package.json +3 -2
  46. package/static/main.js +1 -1
package/README.md CHANGED
@@ -2,9 +2,6 @@
2
2
 
3
3
  Documentation generator for TypeScript projects.
4
4
 
5
- [![CI](https://github.com/TypeStrong/typedoc/workflows/CI/badge.svg)](https://github.com/TypeStrong/typedoc/actions)
6
- [![NPM Version](https://img.shields.io/npm/v/typedoc?color=33cd56&logo=npm)](https://www.npmjs.com/package/typedoc)
7
-
8
5
  ## Documentation
9
6
 
10
7
  For more detailed documentation, the changelog, and TypeDoc documentation rendered with TypeDoc, see https://typedoc.org.
package/dist/index.d.ts CHANGED
@@ -1,5 +1,10 @@
1
1
  /**
2
2
  * @module TypeDoc API
3
+ *
4
+ * In addition to the members documented here, TypeDoc exports a `typedoc/debug`
5
+ * entry point which exports some functions which may be useful during plugin
6
+ * development or debugging. Exports from that entry point are **not stable**
7
+ * and may change or be removed at any time.
3
8
  */
4
9
  export { Application, type ApplicationEvents } from "./lib/application.js";
5
10
  export { EventDispatcher } from "./lib/utils/events.js";
package/dist/index.js CHANGED
@@ -1,5 +1,10 @@
1
1
  /**
2
2
  * @module TypeDoc API
3
+ *
4
+ * In addition to the members documented here, TypeDoc exports a `typedoc/debug`
5
+ * entry point which exports some functions which may be useful during plugin
6
+ * development or debugging. Exports from that entry point are **not stable**
7
+ * and may change or be removed at any time.
3
8
  */
4
9
  export { Application } from "./lib/application.js";
5
10
  export { EventDispatcher } from "./lib/utils/events.js";
@@ -107,17 +107,29 @@ function* lexBlockComment2(file, pos, end, linkTags, checker) {
107
107
  break;
108
108
  case "`": {
109
109
  // Markdown's code rules are a royal pain. This could be one of several things.
110
- // 1. Inline code: <1-n ticks><text><same number of ticks>
111
- // 2. Code block: <3 ticks><language, no ticks>\n<text>\n<3 ticks>\n
110
+ // 1. Inline code: <1-n ticks><text without multiple consecutive newlines or ticks at start of line><same number of ticks>
111
+ // 2. Code block: <newline><3+ ticks><language, no ticks>\n<text>\n<3 ticks>\n
112
112
  // 3. Unmatched tick(s), not code, but part of some text.
113
113
  // We don't quite handle #2 correctly yet. PR welcome!
114
114
  braceStartsType = false;
115
115
  let tickCount = 1;
116
- let lookahead = pos;
116
+ let lookahead = pos - 1;
117
+ let atNewline = true;
118
+ while (lookahead > 0 && file[lookahead] !== "\n") {
119
+ if (/\S/.test(file[lookahead])) {
120
+ if (!commentHasStars || file[lookahead] !== "*") {
121
+ atNewline = false;
122
+ break;
123
+ }
124
+ }
125
+ --lookahead;
126
+ }
127
+ lookahead = pos;
117
128
  while (lookahead + 1 < end && file[lookahead + 1] === "`") {
118
129
  tickCount++;
119
130
  lookahead++;
120
131
  }
132
+ const isCodeBlock = atNewline && tickCount >= 3;
121
133
  let lookaheadStart = pos;
122
134
  const codeText = [];
123
135
  lookahead++;
@@ -125,12 +137,18 @@ function* lexBlockComment2(file, pos, end, linkTags, checker) {
125
137
  if (lookaheadExactlyNTicks(lookahead, tickCount)) {
126
138
  lookahead += tickCount;
127
139
  codeText.push(file.substring(lookaheadStart, lookahead));
128
- yield {
129
- kind: TokenSyntaxKind.Code,
130
- text: codeText.join(""),
131
- pos,
132
- };
133
- pos = lookahead;
140
+ const codeTextStr = codeText.join("");
141
+ if (isCodeBlock || !/\n\s*\n/.test(codeTextStr)) {
142
+ yield {
143
+ kind: TokenSyntaxKind.Code,
144
+ text: codeTextStr,
145
+ pos,
146
+ };
147
+ pos = lookahead;
148
+ }
149
+ else {
150
+ yield makeToken(TokenSyntaxKind.Text, tickCount);
151
+ }
134
152
  break;
135
153
  }
136
154
  else if (file[lookahead] === "`") {
@@ -167,7 +185,7 @@ function* lexBlockComment2(file, pos, end, linkTags, checker) {
167
185
  }
168
186
  }
169
187
  if (lookahead >= end && pos !== lookahead) {
170
- if (tickCount === 3 &&
188
+ if (isCodeBlock &&
171
189
  file.substring(pos, end).includes("\n")) {
172
190
  codeText.push(file.substring(lookaheadStart, end));
173
191
  yield {
@@ -174,8 +174,14 @@ function resolveKeyword(refl, kw) {
174
174
  function resolveSymbolReferencePart(refl, path) {
175
175
  let high = [];
176
176
  let low = [];
177
- if (!(refl instanceof ContainerReflection) ||
178
- !refl.childrenIncludingDocuments) {
177
+ let children;
178
+ if (refl instanceof ContainerReflection) {
179
+ children = refl.childrenIncludingDocuments;
180
+ }
181
+ if (!children && refl.isDeclaration() && refl.type?.type === "reflection") {
182
+ children = refl.type.declaration.childrenIncludingDocuments;
183
+ }
184
+ if (!children) {
179
185
  return { high, low };
180
186
  }
181
187
  switch (path.navigation) {
@@ -184,16 +190,16 @@ function resolveSymbolReferencePart(refl, path) {
184
190
  // so that resolution doesn't behave very poorly with projects using JSDoc style resolution.
185
191
  // Also is more consistent with how TypeScript resolves link tags.
186
192
  case ".":
187
- high = refl.childrenIncludingDocuments.filter((r) => r.name === path.path &&
193
+ high = children.filter((r) => r.name === path.path &&
188
194
  (r.kindOf(ReflectionKind.SomeExport) || r.flags.isStatic));
189
- low = refl.childrenIncludingDocuments.filter((r) => r.name === path.path &&
195
+ low = children.filter((r) => r.name === path.path &&
190
196
  (!r.kindOf(ReflectionKind.SomeExport) || !r.flags.isStatic));
191
197
  break;
192
198
  // Resolve via "members", interface children, class instance properties/accessors/methods,
193
199
  // enum members, type literal properties
194
200
  case "#":
195
201
  high =
196
- refl.children?.filter((r) => {
202
+ children?.filter((r) => {
197
203
  return (r.name === path.path &&
198
204
  r.kindOf(ReflectionKind.SomeMember) &&
199
205
  !r.flags.isStatic);
@@ -203,7 +209,7 @@ function resolveSymbolReferencePart(refl, path) {
203
209
  // module/namespace exports since TypeDoc doesn't support documenting locals.
204
210
  case "~":
205
211
  if (refl.kindOf(ReflectionKind.SomeModule | ReflectionKind.Project)) {
206
- high = refl.children?.filter((r) => r.name === path.path) || [];
212
+ high = children?.filter((r) => r.name === path.path) || [];
207
213
  }
208
214
  break;
209
215
  }
@@ -65,11 +65,21 @@ function* lexLineComments2(file, pos, end) {
65
65
  // We don't quite handle #2 correctly yet. PR welcome!
66
66
  braceStartsType = false;
67
67
  let tickCount = 1;
68
- let lookahead = pos;
68
+ let lookahead = pos - 1;
69
+ let atNewline = true;
70
+ while (lookahead > 0 && file[lookahead] !== "\n") {
71
+ if (/\S/.test(file[lookahead])) {
72
+ atNewline = false;
73
+ break;
74
+ }
75
+ --lookahead;
76
+ }
77
+ lookahead = pos;
69
78
  while (lookahead + 1 < end && file[lookahead + 1] === "`") {
70
79
  tickCount++;
71
80
  lookahead++;
72
81
  }
82
+ const isCodeBlock = atNewline && tickCount >= 3;
73
83
  let lookaheadStart = pos;
74
84
  const codeText = [];
75
85
  lookahead++;
@@ -77,12 +87,18 @@ function* lexLineComments2(file, pos, end) {
77
87
  if (lookaheadExactlyNTicks(lookahead, tickCount)) {
78
88
  lookahead += tickCount;
79
89
  codeText.push(file.substring(lookaheadStart, lookahead));
80
- yield {
81
- kind: TokenSyntaxKind.Code,
82
- text: codeText.join(""),
83
- pos,
84
- };
85
- pos = lookahead;
90
+ const codeTextStr = codeText.join("");
91
+ if (isCodeBlock || !/\n\s*\n/.test(codeTextStr)) {
92
+ yield {
93
+ kind: TokenSyntaxKind.Code,
94
+ text: codeTextStr,
95
+ pos,
96
+ };
97
+ pos = lookahead;
98
+ }
99
+ else {
100
+ yield makeToken(TokenSyntaxKind.Text, tickCount);
101
+ }
86
102
  break;
87
103
  }
88
104
  else if (file[lookahead] === "`") {
@@ -1,5 +1,5 @@
1
1
  import ts from "typescript";
2
- import { DeclarationReflection, Reflection, ReflectionSymbolId, } from "../../models/index.js";
2
+ import { DeclarationReflection, Reflection, ReflectionKind, ReflectionSymbolId, } from "../../models/index.js";
3
3
  import { parseDeclarationReference, } from "./declarationReference.js";
4
4
  import { resolveDeclarationReference } from "./declarationReferenceResolver.js";
5
5
  const urlPrefix = /^(http|ftp)s?:\/\//;
@@ -45,9 +45,14 @@ function resolveLinkTag(reflection, part, externalResolver, options) {
45
45
  const declRef = parseDeclarationReference(part.text, pos, end);
46
46
  // Might already know where it should go if useTsLinkResolution is turned on
47
47
  if (part.target instanceof ReflectionSymbolId) {
48
- const tsTarget = reflection.project.getReflectionFromSymbolId(part.target);
49
- if (tsTarget) {
50
- target = tsTarget;
48
+ const tsTargets = reflection.project.getReflectionsFromSymbolId(part.target);
49
+ if (tsTargets.length) {
50
+ // Find the target most likely to have a real url in the generated documentation
51
+ target =
52
+ tsTargets.find((r) => r.kindOf(ReflectionKind.SomeExport)) ||
53
+ tsTargets.find((r) => r.kindOf(ReflectionKind.SomeMember) &&
54
+ r.parent?.kindOf(ReflectionKind.SomeExport)) ||
55
+ tsTargets[0];
51
56
  pos = end;
52
57
  defaultDisplayText =
53
58
  part.tsLinkText ||
@@ -43,19 +43,14 @@ function* lexCommentString2(file) {
43
43
  while (pos < end && /\s/.test(file[end - 1])) {
44
44
  end--;
45
45
  }
46
- let lineStart = true;
47
46
  let expectingTag = false;
48
47
  for (;;) {
49
48
  if (pos >= end) {
50
49
  return;
51
50
  }
52
- if (lineStart) {
53
- lineStart = false;
54
- }
55
51
  switch (file[pos]) {
56
52
  case "\n":
57
53
  yield makeToken(TokenSyntaxKind.NewLine, 1);
58
- lineStart = true;
59
54
  expectingTag = false;
60
55
  break;
61
56
  case "{":
@@ -68,16 +63,26 @@ function* lexCommentString2(file) {
68
63
  break;
69
64
  case "`": {
70
65
  // Markdown's code rules are a royal pain. This could be one of several things.
71
- // 1. Inline code: <1-n ticks><text><same number of ticks>
72
- // 2. Code block: <3 ticks><language, no ticks>\n<text>\n<3 ticks>\n
66
+ // 1. Inline code: <1-n ticks><text without multiple consecutive newlines or ticks at start of line><same number of ticks>
67
+ // 2. Code block: <newline><3+ ticks><language, no ticks>\n<text>\n<3 ticks>\n
73
68
  // 3. Unmatched tick(s), not code, but part of some text.
74
69
  // We don't quite handle #2 correctly yet. PR welcome!
75
70
  let tickCount = 1;
76
- let lookahead = pos;
71
+ let lookahead = pos - 1;
72
+ let atNewline = true;
73
+ while (lookahead > 0 && file[lookahead] !== "\n") {
74
+ if (/\S/.test(file[lookahead])) {
75
+ atNewline = false;
76
+ break;
77
+ }
78
+ --lookahead;
79
+ }
80
+ lookahead = pos;
77
81
  while (lookahead + 1 < end && file[lookahead + 1] === "`") {
78
82
  tickCount++;
79
83
  lookahead++;
80
84
  }
85
+ const isCodeBlock = atNewline && tickCount >= 3;
81
86
  let lookaheadStart = pos;
82
87
  const codeText = [];
83
88
  lookahead++;
@@ -85,13 +90,20 @@ function* lexCommentString2(file) {
85
90
  if (lookaheadExactlyNTicks(lookahead, tickCount)) {
86
91
  lookahead += tickCount;
87
92
  codeText.push(file.substring(lookaheadStart, lookahead));
88
- yield {
89
- kind: TokenSyntaxKind.Code,
90
- text: codeText.join(""),
91
- pos,
92
- };
93
- expectingTag = false;
94
- pos = lookahead;
93
+ const codeTextStr = codeText.join("");
94
+ if (isCodeBlock || !/\n\s*\n/.test(codeTextStr)) {
95
+ yield {
96
+ kind: TokenSyntaxKind.Code,
97
+ text: codeTextStr,
98
+ pos,
99
+ };
100
+ expectingTag = false;
101
+ pos = lookahead;
102
+ }
103
+ else {
104
+ yield makeToken(TokenSyntaxKind.Text, tickCount);
105
+ expectingTag = false;
106
+ }
95
107
  break;
96
108
  }
97
109
  else if (file[lookahead] === "`") {
@@ -114,7 +126,7 @@ function* lexCommentString2(file) {
114
126
  }
115
127
  }
116
128
  if (lookahead >= end && pos !== lookahead) {
117
- if (tickCount === 3 &&
129
+ if (isCodeBlock &&
118
130
  file.substring(pos, end).includes("\n")) {
119
131
  codeText.push(file.substring(lookaheadStart, end));
120
132
  yield {
@@ -81,6 +81,7 @@ export function textContent(sourcePath, token, i18n, warning, outContent, files,
81
81
  addRef(tagLink);
82
82
  continue;
83
83
  }
84
+ data.atNewLine = token.text[data.pos] === "\n";
84
85
  ++data.pos;
85
86
  }
86
87
  if (lastPartEnd !== token.text.length) {
@@ -1,6 +1,7 @@
1
1
  export declare const ConverterEvents: {
2
2
  readonly BEGIN: "begin";
3
3
  readonly END: "end";
4
+ readonly CREATE_PROJECT: "createProject";
4
5
  readonly CREATE_DECLARATION: "createDeclaration";
5
6
  readonly CREATE_DOCUMENT: "createDocument";
6
7
  readonly CREATE_SIGNATURE: "createSignature";
@@ -1,6 +1,7 @@
1
1
  export const ConverterEvents = {
2
2
  BEGIN: "begin",
3
3
  END: "end",
4
+ CREATE_PROJECT: "createProject",
4
5
  CREATE_DECLARATION: "createDeclaration",
5
6
  CREATE_DOCUMENT: "createDocument",
6
7
  CREATE_SIGNATURE: "createSignature",
@@ -13,6 +13,7 @@ import type { FileRegistry } from "../models/FileRegistry.js";
13
13
  export interface ConverterEvents {
14
14
  begin: [Context];
15
15
  end: [Context];
16
+ createProject: [Context, ProjectReflection];
16
17
  createDeclaration: [Context, DeclarationReflection];
17
18
  createDocument: [undefined, DocumentReflection];
18
19
  createSignature: [
@@ -83,12 +84,25 @@ export declare class Converter extends AbstractComponent<Application, ConverterE
83
84
  /**
84
85
  * Factory events
85
86
  */
87
+ /**
88
+ * Triggered when the converter has created a project reflection.
89
+ * The listener will be given {@link Context} and a {@link Models.ProjectReflection}.
90
+ * @event
91
+ */
92
+ static readonly EVENT_CREATE_PROJECT: "createProject";
86
93
  /**
87
94
  * Triggered when the converter has created a declaration reflection.
88
95
  * The listener will be given {@link Context} and a {@link Models.DeclarationReflection}.
89
96
  * @event
90
97
  */
91
98
  static readonly EVENT_CREATE_DECLARATION: "createDeclaration";
99
+ /**
100
+ * Triggered when the converter has created a document reflection.
101
+ * The listener will be given `undefined` (for consistency with the
102
+ * other create events) and a {@link Models.DocumentReflection}.
103
+ * @event
104
+ */
105
+ static readonly EVENT_CREATE_DOCUMENT: "createDocument";
92
106
  /**
93
107
  * Triggered when the converter has created a signature reflection.
94
108
  * The listener will be given {@link Context}, {@link Models.SignatureReflection} | {@link Models.ProjectReflection} the declaration,
@@ -195,12 +195,25 @@ let Converter = (() => {
195
195
  /**
196
196
  * Factory events
197
197
  */
198
+ /**
199
+ * Triggered when the converter has created a project reflection.
200
+ * The listener will be given {@link Context} and a {@link Models.ProjectReflection}.
201
+ * @event
202
+ */
203
+ static EVENT_CREATE_PROJECT = ConverterEvents.CREATE_PROJECT;
198
204
  /**
199
205
  * Triggered when the converter has created a declaration reflection.
200
206
  * The listener will be given {@link Context} and a {@link Models.DeclarationReflection}.
201
207
  * @event
202
208
  */
203
209
  static EVENT_CREATE_DECLARATION = ConverterEvents.CREATE_DECLARATION;
210
+ /**
211
+ * Triggered when the converter has created a document reflection.
212
+ * The listener will be given `undefined` (for consistency with the
213
+ * other create events) and a {@link Models.DocumentReflection}.
214
+ * @event
215
+ */
216
+ static EVENT_CREATE_DOCUMENT = ConverterEvents.CREATE_DOCUMENT;
204
217
  /**
205
218
  * Triggered when the converter has created a signature reflection.
206
219
  * The listener will be given {@link Context}, {@link Models.SignatureReflection} | {@link Models.ProjectReflection} the declaration,
@@ -386,6 +399,9 @@ let Converter = (() => {
386
399
  ? opts.getValue("alwaysCreateEntryPointModule")
387
400
  : !!context.scope.documents;
388
401
  }
402
+ if (createModuleReflections) {
403
+ this.trigger(ConverterEvents.CREATE_PROJECT, context, context.project);
404
+ }
389
405
  entries.forEach((e) => {
390
406
  context.setActiveProgram(e.entryPoint.program);
391
407
  e.context = this.convertExports(context, e.entryPoint, createModuleReflections);
@@ -412,6 +428,7 @@ let Converter = (() => {
412
428
  ? context.getComment(symbol, context.project.kind)
413
429
  : context.getFileComment(node);
414
430
  this.processDocumentTags(context.project, context.project);
431
+ this.trigger(ConverterEvents.CREATE_PROJECT, context, context.project);
415
432
  moduleContext = context;
416
433
  }
417
434
  else {
@@ -432,7 +432,7 @@ let CommentPlugin = (() => {
432
432
  }
433
433
  // Any cascaded tags will show up twice, once on this and once on our signatures
434
434
  // This is completely redundant, so remove them from the wrapping function.
435
- if (sigs.length) {
435
+ if (sigs.length && reflection.type?.type !== "reflection") {
436
436
  for (const mod of this.cascadedModifierTags) {
437
437
  reflection.comment.modifierTags.delete(mod);
438
438
  }
@@ -485,8 +485,9 @@ let CommentPlugin = (() => {
485
485
  }
486
486
  cascadeModifiers(reflection) {
487
487
  const parentComment = reflection.parent?.comment;
488
- if (!parentComment)
488
+ if (!parentComment || reflection.kindOf(ReflectionKind.TypeLiteral)) {
489
489
  return;
490
+ }
490
491
  const childMods = reflection.comment?.modifierTags ?? new Set();
491
492
  for (const mod of this.cascadedModifierTags) {
492
493
  if (parentComment.hasModifier(mod)) {
@@ -14,6 +14,7 @@ export class IncludePlugin extends ConverterComponent {
14
14
  constructor(owner) {
15
15
  super(owner);
16
16
  const onCreate = this.onCreate.bind(this);
17
+ owner.on(ConverterEvents.CREATE_PROJECT, onCreate);
17
18
  owner.on(ConverterEvents.CREATE_DOCUMENT, onCreate);
18
19
  owner.on(ConverterEvents.CREATE_DECLARATION, onCreate);
19
20
  owner.on(ConverterEvents.CREATE_PARAMETER, onCreate);
@@ -0,0 +1,2 @@
1
+ import type { Application } from "../application.js";
2
+ export declare function debugReflectionLifetimes(app: Application): void;
@@ -0,0 +1,19 @@
1
+ import { ConverterEvents } from "../converter/converter-events.js";
2
+ export function debugReflectionLifetimes(app) {
3
+ app.converter.on(ConverterEvents.CREATE_PROJECT, logCreate);
4
+ app.converter.on(ConverterEvents.CREATE_SIGNATURE, logCreate);
5
+ app.converter.on(ConverterEvents.CREATE_TYPE_PARAMETER, logCreate);
6
+ app.converter.on(ConverterEvents.CREATE_DECLARATION, logCreate);
7
+ app.converter.on(ConverterEvents.CREATE_DOCUMENT, logCreate);
8
+ app.converter.on(ConverterEvents.CREATE_PARAMETER, logCreate);
9
+ app.converter.on(ConverterEvents.CREATE_PROJECT, (_context, project) => {
10
+ const oldRemove = project["_removeReflection"];
11
+ project["_removeReflection"] = function (reflection) {
12
+ console.log("Remove", reflection.id, reflection.getFullName());
13
+ return oldRemove.call(this, reflection);
14
+ };
15
+ });
16
+ }
17
+ function logCreate(_context, refl) {
18
+ console.log("Create", refl.variant, refl.id, refl.getFullName());
19
+ }
@@ -0,0 +1,5 @@
1
+ import type { Application } from "../application.js";
2
+ export declare function debugRendererUrls(app: Application, { json, logs }?: {
3
+ logs?: true;
4
+ json?: boolean | undefined;
5
+ }): void;
@@ -0,0 +1,59 @@
1
+ /* eslint-disable no-console */
2
+ import { join } from "node:path";
3
+ import { Reflection, ReflectionKind, } from "../models/index.js";
4
+ const serializer = {
5
+ priority: 0,
6
+ supports(x) {
7
+ return x instanceof Reflection;
8
+ },
9
+ toObject(item, obj) {
10
+ obj.url = item.url;
11
+ obj.hasOwnDocument = item.hasOwnDocument;
12
+ // obj.anchor = item.anchor;
13
+ delete obj.sources;
14
+ delete obj.groups;
15
+ delete obj.categories;
16
+ delete obj.readme;
17
+ delete obj.content;
18
+ obj.kind = ReflectionKind[obj.kind];
19
+ delete obj.flags;
20
+ delete obj.defaultValue;
21
+ delete obj.symbolIdMap;
22
+ delete obj.files;
23
+ delete obj.packageName;
24
+ delete obj.variant;
25
+ delete obj.extendedTypes;
26
+ delete obj.inheritedFrom;
27
+ if (!["reflection", "reference"].includes(obj.type?.type)) {
28
+ delete obj.type;
29
+ }
30
+ if (obj.comment) {
31
+ obj.comment.summary = obj.comment.summary.filter((part) => part.kind === "inline-tag");
32
+ obj.comment.blockTags = obj.comment.blockTags?.filter((tag) => {
33
+ tag.content = tag.content.filter((part) => part.kind === "inline-tag");
34
+ return tag.content.length;
35
+ });
36
+ if (!obj.comment.summary.length &&
37
+ !obj.comment.blockTags?.length &&
38
+ !obj.comment.modifierTags) {
39
+ delete obj.comment;
40
+ }
41
+ }
42
+ return obj;
43
+ },
44
+ };
45
+ export function debugRendererUrls(app, { json = false, logs = false } = { logs: true }) {
46
+ app.renderer.postRenderAsyncJobs.push(async (evt) => {
47
+ if (json) {
48
+ app.serializer.addSerializer(serializer);
49
+ await app.generateJson(evt.project, join(evt.outputDirectory, "url_debug.json"));
50
+ app.serializer.removeSerializer(serializer);
51
+ }
52
+ if (logs) {
53
+ for (const id in evt.project.reflections) {
54
+ const refl = evt.project.reflections[id];
55
+ console.log(refl.id, refl.getFullName(), refl.url, refl.hasOwnDocument);
56
+ }
57
+ }
58
+ });
59
+ }
@@ -0,0 +1,2 @@
1
+ export { debugRendererUrls } from "./debugRendererUrls.js";
2
+ export { debugReflectionLifetimes } from "./debugReflectionLifetimes.js";
@@ -0,0 +1,2 @@
1
+ export { debugRendererUrls } from "./debugRendererUrls.js";
2
+ export { debugReflectionLifetimes } from "./debugReflectionLifetimes.js";
@@ -2,7 +2,6 @@ import type { Application } from "../application.js";
2
2
  import { ReflectionKind } from "../models/reflections/kind.js";
3
3
  import { ReflectionFlag } from "../models/index.js";
4
4
  import { type BuiltinTranslatableStringArgs } from "./translatable.js";
5
- import translatable from "./locales/en.cjs";
6
5
  /**
7
6
  * ### What is translatable?
8
7
  * TypeDoc includes a lot of literal strings. By convention, messages which are displayed
@@ -75,7 +74,7 @@ export declare class Internationalization {
75
74
  * Get the translation of the specified key, replacing placeholders
76
75
  * with the arguments specified.
77
76
  */
78
- translate<T extends keyof typeof translatable>(key: T, ...args: TranslatableStrings[T]): TranslatedString;
77
+ translate<T extends keyof TranslatableStrings>(key: T, ...args: TranslatableStrings[T]): TranslatedString;
79
78
  kindSingularString(kind: ReflectionKind): TranslatedString;
80
79
  kindPluralString(kind: ReflectionKind): TranslatedString;
81
80
  flagString(flag: ReflectionFlag): TranslatedString;
@@ -61,6 +61,7 @@ module.exports = {
61
61
  reflection_0_kind_1_defined_in_2_does_not_have_any_documentation: `{0} ({1}), defined in {2}, does not have any documentation`,
62
62
  invalid_intentionally_not_exported_symbols_0: "The following symbols were marked as intentionally not exported, but were either not referenced in the documentation, or were exported:\n\t{0}",
63
63
  reflection_0_has_unused_mergeModuleWith_tag: "{0} has a @mergeModuleWith tag which could not be resolved",
64
+ reflection_0_links_to_1_with_text_2_but_resolved_to_3: `"{0}" links to "{1}" with text "{2}" which exists but does not have a link in the documentation, will link to "{3}" instead.`,
64
65
  // conversion plugins
65
66
  not_all_search_category_boosts_used_0: `Not all categories specified in searchCategoryBoosts were used in the documentation. The unused categories were:\n\t{0}`,
66
67
  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}`,
@@ -56,6 +56,7 @@ declare const _default: {
56
56
  readonly reflection_0_kind_1_defined_in_2_does_not_have_any_documentation: "{0} ({1}), defined in {2}, does not have any documentation";
57
57
  readonly invalid_intentionally_not_exported_symbols_0: "The following symbols were marked as intentionally not exported, but were either not referenced in the documentation, or were exported:\n\t{0}";
58
58
  readonly reflection_0_has_unused_mergeModuleWith_tag: "{0} has a @mergeModuleWith tag which could not be resolved";
59
+ readonly reflection_0_links_to_1_with_text_2_but_resolved_to_3: "\"{0}\" links to \"{1}\" with text \"{2}\" which exists but does not have a link in the documentation, will link to \"{3}\" instead.";
59
60
  readonly not_all_search_category_boosts_used_0: "Not all categories specified in searchCategoryBoosts were used in the documentation. The unused categories were:\n\t{0}";
60
61
  readonly 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}";
61
62
  readonly 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";
@@ -52,7 +52,7 @@ export class ReflectionCategory {
52
52
  de.defer((project) => {
53
53
  for (const childId of obj.children || []) {
54
54
  const child = project.getReflectionById(de.oldIdToNewId[childId] ?? -1);
55
- if (child?.isDeclaration()) {
55
+ if (child?.isDeclaration() || child?.isDocument()) {
56
56
  this.children.push(child);
57
57
  }
58
58
  }
@@ -68,7 +68,7 @@ export class ReflectionGroup {
68
68
  de.defer((project) => {
69
69
  for (const childId of obj.children || []) {
70
70
  const child = project.getReflectionById(de.oldIdToNewId[childId] ?? -1);
71
- if (child?.isDeclaration()) {
71
+ if (child?.isDeclaration() || child?.isDocument()) {
72
72
  this.children.push(child);
73
73
  }
74
74
  }
@@ -294,6 +294,7 @@ export class ProjectReflection extends ContainerReflection {
294
294
  }
295
295
  /** @internal */
296
296
  registerSymbolId(reflection, id) {
297
+ this.removedSymbolIds.delete(id);
297
298
  this.reflectionIdToSymbolIdMap.set(reflection.id, id);
298
299
  const previous = this.symbolToReflectionIdMap.get(id);
299
300
  if (previous) {
@@ -690,7 +690,11 @@ export class ReferenceType extends Type {
690
690
  : ReflectionKind.TypeReferenceTarget;
691
691
  const resolved = resolvePotential.find((refl) => refl.kindOf(kind)) ||
692
692
  resolvePotential.find((refl) => refl.kindOf(~kind));
693
- this._target = resolved.id;
693
+ // Do not mark the type as resolved at this point so that if it
694
+ // points to a member which is removed (e.g. by typedoc-plugin-zod)
695
+ // and then replaced it still ends up pointing at the right reflection.
696
+ // We will lock type reference resolution when serializing to JSON.
697
+ // this._target = resolved.id;
694
698
  return resolved;
695
699
  }
696
700
  /**
@@ -820,6 +824,9 @@ export class ReferenceType extends Type {
820
824
  else if (this._project?.symbolIdHasBeenRemoved(this._target)) {
821
825
  target = -1;
822
826
  }
827
+ else if (this.reflection) {
828
+ target = this.reflection.id;
829
+ }
823
830
  else {
824
831
  target = this._target.toObject(serializer);
825
832
  }
@@ -837,7 +844,7 @@ export class ReferenceType extends Type {
837
844
  if (this.refersToTypeParameter) {
838
845
  result.refersToTypeParameter = true;
839
846
  }
840
- if (typeof this._target !== "number" && this.preferValues) {
847
+ if (typeof target !== "number" && this.preferValues) {
841
848
  result.preferValues = true;
842
849
  }
843
850
  if (this.highlightedProperties) {