typedoc 0.25.6 → 0.25.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 (44) hide show
  1. package/dist/index.d.ts +7 -0
  2. package/dist/index.js +7 -0
  3. package/dist/lib/converter/comments/discovery.d.ts +1 -0
  4. package/dist/lib/converter/comments/discovery.js +19 -1
  5. package/dist/lib/converter/comments/index.d.ts +1 -0
  6. package/dist/lib/converter/comments/index.js +5 -1
  7. package/dist/lib/converter/context.d.ts +1 -0
  8. package/dist/lib/converter/context.js +3 -0
  9. package/dist/lib/converter/converter.js +1 -1
  10. package/dist/lib/converter/factories/signature.d.ts +5 -1
  11. package/dist/lib/converter/factories/signature.js +25 -1
  12. package/dist/lib/converter/plugins/CategoryPlugin.js +19 -3
  13. package/dist/lib/converter/plugins/GroupPlugin.d.ts +2 -2
  14. package/dist/lib/converter/plugins/GroupPlugin.js +18 -2
  15. package/dist/lib/converter/plugins/LinkResolverPlugin.d.ts +1 -0
  16. package/dist/lib/converter/plugins/LinkResolverPlugin.js +24 -0
  17. package/dist/lib/converter/symbols.js +59 -6
  18. package/dist/lib/converter/types.js +1 -4
  19. package/dist/lib/models/ReflectionCategory.d.ts +6 -2
  20. package/dist/lib/models/ReflectionCategory.js +8 -1
  21. package/dist/lib/models/ReflectionGroup.d.ts +5 -1
  22. package/dist/lib/models/ReflectionGroup.js +7 -0
  23. package/dist/lib/models/comments/comment.d.ts +10 -1
  24. package/dist/lib/models/comments/comment.js +45 -0
  25. package/dist/lib/output/plugins/SitemapPlugin.d.ts +7 -0
  26. package/dist/lib/output/plugins/SitemapPlugin.js +152 -0
  27. package/dist/lib/output/plugins/index.d.ts +1 -0
  28. package/dist/lib/output/plugins/index.js +3 -1
  29. package/dist/lib/output/themes/default/DefaultTheme.js +1 -13
  30. package/dist/lib/output/themes/default/partials/index.js +3 -1
  31. package/dist/lib/output/themes/default/templates/hierarchy.d.ts +1 -1
  32. package/dist/lib/output/themes/default/templates/hierarchy.js +8 -9
  33. package/dist/lib/output/themes/lib.d.ts +2 -1
  34. package/dist/lib/output/themes/lib.js +24 -1
  35. package/dist/lib/serialization/schema.d.ts +2 -2
  36. package/dist/lib/utils/entry-point.js +1 -1
  37. package/dist/lib/utils/events.js +1 -0
  38. package/dist/lib/utils/options/declaration.d.ts +1 -0
  39. package/dist/lib/utils/options/sources/typedoc.js +9 -0
  40. package/dist/lib/utils/options/tsdoc-defaults.d.ts +2 -2
  41. package/dist/lib/utils/options/tsdoc-defaults.js +4 -1
  42. package/package.json +3 -3
  43. package/static/main.js +4 -4
  44. package/tsdoc.json +14 -0
package/dist/index.d.ts CHANGED
@@ -3,6 +3,13 @@ export { EventDispatcher, Event } from "./lib/utils/events";
3
3
  export { resetReflectionID } from "./lib/models/reflections/abstract";
4
4
  /**
5
5
  * All symbols documented under the Models namespace are also available in the root import.
6
+ *
7
+ * @categoryDescription Types
8
+ * Describes a TypeScript type.
9
+ *
10
+ * @categoryDescription Reflections
11
+ * Describes a documentation entry. The root entry is a {@link ProjectReflection}
12
+ * and contains {@link DeclarationReflection} instances.
6
13
  */
7
14
  export * as Models from "./lib/models";
8
15
  /**
package/dist/index.js CHANGED
@@ -39,6 +39,13 @@ var abstract_1 = require("./lib/models/reflections/abstract");
39
39
  Object.defineProperty(exports, "resetReflectionID", { enumerable: true, get: function () { return abstract_1.resetReflectionID; } });
40
40
  /**
41
41
  * All symbols documented under the Models namespace are also available in the root import.
42
+ *
43
+ * @categoryDescription Types
44
+ * Describes a TypeScript type.
45
+ *
46
+ * @categoryDescription Reflections
47
+ * Describes a documentation entry. The root entry is a {@link ProjectReflection}
48
+ * and contains {@link DeclarationReflection} instances.
42
49
  */
43
50
  exports.Models = __importStar(require("./lib/models"));
44
51
  /**
@@ -12,5 +12,6 @@ export declare function discoverFileComment(node: ts.SourceFile, commentStyle: C
12
12
  ranges: ts.CommentRange[];
13
13
  jsDoc: ts.JSDoc | undefined;
14
14
  } | undefined;
15
+ export declare function discoverNodeComment(node: ts.Node, commentStyle: CommentStyle): DiscoveredComment | undefined;
15
16
  export declare function discoverComment(symbol: ts.Symbol, kind: ReflectionKind, logger: Logger, commentStyle: CommentStyle): DiscoveredComment | undefined;
16
17
  export declare function discoverSignatureComment(declaration: ts.SignatureDeclaration | ts.JSDocSignature, commentStyle: CommentStyle): DiscoveredComment | undefined;
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.discoverSignatureComment = exports.discoverComment = exports.discoverFileComment = void 0;
6
+ exports.discoverSignatureComment = exports.discoverComment = exports.discoverNodeComment = exports.discoverFileComment = void 0;
7
7
  const typescript_1 = __importDefault(require("typescript"));
8
8
  const models_1 = require("../../models");
9
9
  const utils_1 = require("../../utils");
@@ -69,6 +69,10 @@ const wantedKinds = {
69
69
  [models_1.ReflectionKind.Class]: [
70
70
  typescript_1.default.SyntaxKind.ClassDeclaration,
71
71
  typescript_1.default.SyntaxKind.BindingElement,
72
+ // If marked with @class
73
+ typescript_1.default.SyntaxKind.VariableDeclaration,
74
+ typescript_1.default.SyntaxKind.ExportAssignment,
75
+ typescript_1.default.SyntaxKind.FunctionDeclaration,
72
76
  ],
73
77
  [models_1.ReflectionKind.Interface]: [
74
78
  typescript_1.default.SyntaxKind.InterfaceDeclaration,
@@ -116,6 +120,20 @@ function discoverFileComment(node, commentStyle) {
116
120
  }
117
121
  }
118
122
  exports.discoverFileComment = discoverFileComment;
123
+ function discoverNodeComment(node, commentStyle) {
124
+ const text = node.getSourceFile().text;
125
+ const comments = collectCommentRanges(typescript_1.default.getLeadingCommentRanges(text, node.pos));
126
+ comments.reverse();
127
+ const selectedDocComment = comments.find((ranges) => permittedRange(text, ranges, commentStyle));
128
+ if (selectedDocComment) {
129
+ return {
130
+ file: node.getSourceFile(),
131
+ ranges: selectedDocComment,
132
+ jsDoc: findJsDocForComment(node, selectedDocComment),
133
+ };
134
+ }
135
+ }
136
+ exports.discoverNodeComment = discoverNodeComment;
119
137
  function discoverComment(symbol, kind, logger, commentStyle) {
120
138
  // For a module comment, we want the first one defined in the file,
121
139
  // not the last one, since that will apply to the import or declaration.
@@ -10,6 +10,7 @@ export interface CommentParserConfig {
10
10
  }
11
11
  export declare function clearCommentCache(): void;
12
12
  export declare function getComment(symbol: ts.Symbol, kind: ReflectionKind, config: CommentParserConfig, logger: Logger, commentStyle: CommentStyle, checker: ts.TypeChecker | undefined): Comment | undefined;
13
+ export declare function getNodeComment(node: ts.Node, kind: ReflectionKind, config: CommentParserConfig, logger: Logger, commentStyle: CommentStyle, checker: ts.TypeChecker | undefined): Comment | undefined;
13
14
  export declare function getFileComment(file: ts.SourceFile, config: CommentParserConfig, logger: Logger, commentStyle: CommentStyle, checker: ts.TypeChecker | undefined): Comment | undefined;
14
15
  export declare function getSignatureComment(declaration: ts.SignatureDeclaration | ts.JSDocSignature, config: CommentParserConfig, logger: Logger, commentStyle: CommentStyle, checker: ts.TypeChecker | undefined): Comment | undefined;
15
16
  export declare function getJsDocComment(declaration: ts.JSDocPropertyLikeTag | ts.JSDocCallbackTag | ts.JSDocTypedefTag | ts.JSDocTemplateTag | ts.JSDocEnumTag, config: CommentParserConfig, logger: Logger, checker: ts.TypeChecker | undefined): Comment | undefined;
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.getJsDocComment = exports.getSignatureComment = exports.getFileComment = exports.getComment = exports.clearCommentCache = void 0;
6
+ exports.getJsDocComment = exports.getSignatureComment = exports.getFileComment = exports.getNodeComment = exports.getComment = exports.clearCommentCache = void 0;
7
7
  const typescript_1 = __importDefault(require("typescript"));
8
8
  const models_1 = require("../../models");
9
9
  const utils_1 = require("../../utils");
@@ -89,6 +89,10 @@ function getComment(symbol, kind, config, logger, commentStyle, checker) {
89
89
  return comment;
90
90
  }
91
91
  exports.getComment = getComment;
92
+ function getNodeComment(node, kind, config, logger, commentStyle, checker) {
93
+ return getCommentImpl((0, discovery_1.discoverNodeComment)(node, commentStyle), config, logger, kind === models_1.ReflectionKind.Module, checker);
94
+ }
95
+ exports.getNodeComment = getNodeComment;
92
96
  function getFileComment(file, config, logger, commentStyle, checker) {
93
97
  return getCommentImpl((0, discovery_1.discoverFileComment)(file, commentStyle), config, logger,
94
98
  /* moduleComment */ true, checker);
@@ -79,6 +79,7 @@ export declare class Context {
79
79
  /** @internal */
80
80
  setActiveProgram(program: ts.Program | undefined): void;
81
81
  getComment(symbol: ts.Symbol, kind: ReflectionKind): import("../models/index").Comment | undefined;
82
+ getNodeComment(node: ts.Node, kind: ReflectionKind): import("../models/index").Comment | undefined;
82
83
  getFileComment(node: ts.SourceFile): import("../models/index").Comment | undefined;
83
84
  getJsDocComment(declaration: ts.JSDocPropertyLikeTag | ts.JSDocCallbackTag | ts.JSDocTypedefTag | ts.JSDocTemplateTag | ts.JSDocEnumTag): import("../models/index").Comment | undefined;
84
85
  getSignatureComment(declaration: ts.SignatureDeclaration | ts.JSDocSignature): import("../models/index").Comment | undefined;
@@ -175,6 +175,9 @@ class Context {
175
175
  getComment(symbol, kind) {
176
176
  return (0, comments_1.getComment)(symbol, kind, this.converter.config, this.logger, this.converter.commentStyle, this.converter.useTsLinkResolution ? this.checker : undefined);
177
177
  }
178
+ getNodeComment(node, kind) {
179
+ return (0, comments_1.getNodeComment)(node, kind, this.converter.config, this.logger, this.converter.commentStyle, this.converter.useTsLinkResolution ? this.checker : undefined);
180
+ }
178
181
  getFileComment(node) {
179
182
  return (0, comments_1.getFileComment)(node, this.converter.config, this.logger, this.converter.commentStyle, this.converter.useTsLinkResolution ? this.checker : undefined);
180
183
  }
@@ -184,7 +184,7 @@ let Converter = (() => {
184
184
  * Compile the given source files and create a project reflection for them.
185
185
  */
186
186
  convert(entryPoints) {
187
- const programs = entryPoints.map((e) => e.program);
187
+ const programs = (0, utils_1.unique)(entryPoints.map((e) => e.program));
188
188
  this.externalPatternCache = void 0;
189
189
  const project = new index_1.ProjectReflection(this.application.options.getValue("name"));
190
190
  const context = new context_1.Context(this, programs, project);
@@ -1,7 +1,11 @@
1
1
  import ts from "typescript";
2
- import { ParameterReflection, ReflectionKind, SignatureReflection, TypeParameterReflection } from "../../models";
2
+ import { ParameterReflection, Reflection, ReflectionKind, SignatureReflection, TypeParameterReflection } from "../../models";
3
3
  import type { Context } from "../context";
4
4
  export declare function createSignature(context: Context, kind: ReflectionKind.CallSignature | ReflectionKind.ConstructorSignature | ReflectionKind.GetSignature | ReflectionKind.SetSignature, signature: ts.Signature, symbol: ts.Symbol | undefined, declaration?: ts.SignatureDeclaration | ts.JSDocSignature): void;
5
+ /**
6
+ * Special cased constructor factory for functions tagged with `@class`
7
+ */
8
+ export declare function createConstructSignatureWithType(context: Context, signature: ts.Signature, classType: Reflection): void;
5
9
  export declare function convertParameterNodes(context: Context, sigRef: SignatureReflection, parameters: readonly (ts.JSDocParameterTag | ts.ParameterDeclaration)[]): ParameterReflection[];
6
10
  export declare function convertTypeParameterNodes(context: Context, parameters: readonly ts.TypeParameterDeclaration[] | undefined): TypeParameterReflection[] | undefined;
7
11
  export declare function createTypeParamReflection(param: ts.TypeParameterDeclaration, context: Context): TypeParameterReflection;
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.convertTemplateParameterNodes = exports.createTypeParamReflection = exports.convertTypeParameterNodes = exports.convertParameterNodes = exports.createSignature = void 0;
6
+ exports.convertTemplateParameterNodes = exports.createTypeParamReflection = exports.convertTypeParameterNodes = exports.convertParameterNodes = exports.createConstructSignatureWithType = exports.createSignature = void 0;
7
7
  const typescript_1 = __importDefault(require("typescript"));
8
8
  const assert_1 = __importDefault(require("assert"));
9
9
  const models_1 = require("../../models");
@@ -17,6 +17,11 @@ function createSignature(context, kind, signature, symbol, declaration) {
17
17
  const sigRef = new models_1.SignatureReflection(kind == models_1.ReflectionKind.ConstructorSignature
18
18
  ? `new ${context.scope.parent.name}`
19
19
  : context.scope.name, kind, context.scope);
20
+ // This feels awful, but we need some way to tell if callable signatures on classes
21
+ // are "static" (e.g. `Foo()`) or not (e.g. `(new Foo())()`)
22
+ if (context.shouldBeStatic) {
23
+ sigRef.setFlag(models_1.ReflectionFlag.Static);
24
+ }
20
25
  const sigRefCtx = context.withScope(sigRef);
21
26
  if (symbol && declaration) {
22
27
  context.project.registerSymbolId(sigRef, new ReflectionSymbolId_1.ReflectionSymbolId(symbol, declaration));
@@ -72,6 +77,25 @@ function createSignature(context, kind, signature, symbol, declaration) {
72
77
  context.converter.trigger(converter_events_1.ConverterEvents.CREATE_SIGNATURE, context, sigRef, declaration, signature);
73
78
  }
74
79
  exports.createSignature = createSignature;
80
+ /**
81
+ * Special cased constructor factory for functions tagged with `@class`
82
+ */
83
+ function createConstructSignatureWithType(context, signature, classType) {
84
+ (0, assert_1.default)(context.scope instanceof models_1.DeclarationReflection);
85
+ const declaration = signature.getDeclaration();
86
+ const sigRef = new models_1.SignatureReflection(`new ${context.scope.parent.name}`, models_1.ReflectionKind.ConstructorSignature, context.scope);
87
+ const sigRefCtx = context.withScope(sigRef);
88
+ if (declaration) {
89
+ sigRef.comment = context.getSignatureComment(declaration);
90
+ }
91
+ sigRef.typeParameters = convertTypeParameters(sigRefCtx, sigRef, signature.typeParameters);
92
+ sigRef.type = models_1.ReferenceType.createResolvedReference(context.scope.parent.name, classType, context.project);
93
+ context.registerReflection(sigRef, undefined);
94
+ context.scope.signatures ??= [];
95
+ context.scope.signatures.push(sigRef);
96
+ context.converter.trigger(converter_events_1.ConverterEvents.CREATE_SIGNATURE, context, sigRef, declaration, signature);
97
+ }
98
+ exports.createConstructSignatureWithType = createConstructSignatureWithType;
75
99
  function convertParameters(context, sigRef, parameters, parameterNodes) {
76
100
  return parameters.map((param, i) => {
77
101
  const declaration = param.valueDeclaration;
@@ -155,7 +155,7 @@ let CategoryPlugin = (() => {
155
155
  obj.groups.forEach((group) => {
156
156
  if (group.categories)
157
157
  return;
158
- group.categories = this.getReflectionCategories(group.children);
158
+ group.categories = this.getReflectionCategories(obj, group.children);
159
159
  if (group.categories && group.categories.length > 1) {
160
160
  group.categories.sort(CategoryPlugin.sortCatCallback);
161
161
  }
@@ -170,7 +170,7 @@ let CategoryPlugin = (() => {
170
170
  if (!obj.children || obj.children.length === 0 || obj.categories) {
171
171
  return;
172
172
  }
173
- obj.categories = this.getReflectionCategories(obj.children);
173
+ obj.categories = this.getReflectionCategories(obj, obj.children);
174
174
  if (obj.categories && obj.categories.length > 1) {
175
175
  obj.categories.sort(CategoryPlugin.sortCatCallback);
176
176
  }
@@ -188,7 +188,7 @@ let CategoryPlugin = (() => {
188
188
  * relevance boost to be used when searching
189
189
  * @returns An array containing all children of the given reflection categorized
190
190
  */
191
- getReflectionCategories(reflections) {
191
+ getReflectionCategories(parent, reflections) {
192
192
  const categories = new Map();
193
193
  for (const child of reflections) {
194
194
  const childCategories = this.extractCategories(child);
@@ -207,6 +207,22 @@ let CategoryPlugin = (() => {
207
207
  }
208
208
  }
209
209
  }
210
+ if (parent.comment) {
211
+ (0, utils_1.removeIf)(parent.comment.blockTags, (tag) => {
212
+ if (tag.tag === "@categoryDescription") {
213
+ const { header, body } = models_1.Comment.splitPartsToHeaderAndBody(tag.content);
214
+ const cat = categories.get(header);
215
+ if (cat) {
216
+ cat.description = body;
217
+ }
218
+ else {
219
+ this.application.logger.warn(`Comment for ${parent.getFriendlyFullName()} includes @categoryDescription for "${header}", but no child is placed in that category.`);
220
+ }
221
+ return true;
222
+ }
223
+ return false;
224
+ });
225
+ }
210
226
  for (const cat of categories.values()) {
211
227
  this.sortFunction(cat.children);
212
228
  }
@@ -1,4 +1,4 @@
1
- import { DeclarationReflection } from "../../models/reflections/index";
1
+ import { ContainerReflection, DeclarationReflection } from "../../models/reflections/index";
2
2
  import { ReflectionGroup } from "../../models/ReflectionGroup";
3
3
  import { ConverterComponent } from "../components";
4
4
  /**
@@ -39,7 +39,7 @@ export declare class GroupPlugin extends ConverterComponent {
39
39
  * @param reflections The reflections that should be grouped.
40
40
  * @returns An array containing all children of the given reflection grouped by their kind.
41
41
  */
42
- getReflectionGroups(reflections: DeclarationReflection[]): ReflectionGroup[];
42
+ getReflectionGroups(parent: ContainerReflection, reflections: DeclarationReflection[]): ReflectionGroup[];
43
43
  /**
44
44
  * Callback used to sort groups by name.
45
45
  */
@@ -135,7 +135,7 @@ let GroupPlugin = (() => {
135
135
  !reflection.children.some((c) => c.kindOf(index_1.ReflectionKind.Module))) {
136
136
  this.sortFunction(reflection.children);
137
137
  }
138
- reflection.groups = this.getReflectionGroups(reflection.children);
138
+ reflection.groups = this.getReflectionGroups(reflection, reflection.children);
139
139
  }
140
140
  }
141
141
  /**
@@ -188,7 +188,7 @@ let GroupPlugin = (() => {
188
188
  * @param reflections The reflections that should be grouped.
189
189
  * @returns An array containing all children of the given reflection grouped by their kind.
190
190
  */
191
- getReflectionGroups(reflections) {
191
+ getReflectionGroups(parent, reflections) {
192
192
  const groups = new Map();
193
193
  reflections.forEach((child) => {
194
194
  for (const name of this.getGroups(child)) {
@@ -200,6 +200,22 @@ let GroupPlugin = (() => {
200
200
  group.children.push(child);
201
201
  }
202
202
  });
203
+ if (parent.comment) {
204
+ (0, utils_1.removeIf)(parent.comment.blockTags, (tag) => {
205
+ if (tag.tag === "@groupDescription") {
206
+ const { header, body } = models_1.Comment.splitPartsToHeaderAndBody(tag.content);
207
+ const cat = groups.get(header);
208
+ if (cat) {
209
+ cat.description = body;
210
+ }
211
+ else {
212
+ this.application.logger.warn(`Comment for ${parent.getFriendlyFullName()} includes @groupDescription for "${header}", but no child is placed in that group.`);
213
+ }
214
+ return true;
215
+ }
216
+ return false;
217
+ });
218
+ }
203
219
  return Array.from(groups.values()).sort(GroupPlugin.sortGroupCallback);
204
220
  }
205
221
  /**
@@ -10,4 +10,5 @@ export declare class LinkResolverPlugin extends ConverterComponent {
10
10
  initialize(): void;
11
11
  onResolve(context: Context): void;
12
12
  resolveLinks(project: ProjectReflection): void;
13
+ private resolveCategoryLinks;
13
14
  }
@@ -94,6 +94,25 @@ let LinkResolverPlugin = (() => {
94
94
  reflection.readme) {
95
95
  reflection.readme = this.owner.resolveLinks(reflection.readme, reflection);
96
96
  }
97
+ if (reflection instanceof models_1.ContainerReflection) {
98
+ if (reflection.groups) {
99
+ for (const group of reflection.groups) {
100
+ if (group.description) {
101
+ group.description = this.owner.resolveLinks(group.description, reflection);
102
+ }
103
+ if (group.categories) {
104
+ for (const cat of group.categories) {
105
+ this.resolveCategoryLinks(cat, reflection);
106
+ }
107
+ }
108
+ }
109
+ }
110
+ if (reflection.categories) {
111
+ for (const cat of reflection.categories) {
112
+ this.resolveCategoryLinks(cat, reflection);
113
+ }
114
+ }
115
+ }
97
116
  }
98
117
  if (project.readme) {
99
118
  project.readme = this.owner.resolveLinks(project.readme, project);
@@ -112,6 +131,11 @@ let LinkResolverPlugin = (() => {
112
131
  }
113
132
  }
114
133
  }
134
+ resolveCategoryLinks(category, owner) {
135
+ if (category.description) {
136
+ category.description = this.owner.resolveLinks(category.description, owner);
137
+ }
138
+ }
115
139
  };
116
140
  _LinkResolverPlugin_validation_accessor_storage = new WeakMap();
117
141
  __setFunctionName(_classThis, "LinkResolverPlugin");
@@ -47,8 +47,8 @@ const conversionOrder = [
47
47
  typescript_1.default.SymbolFlags.BlockScopedVariable,
48
48
  typescript_1.default.SymbolFlags.FunctionScopedVariable,
49
49
  typescript_1.default.SymbolFlags.ExportValue,
50
- typescript_1.default.SymbolFlags.TypeAlias,
51
50
  typescript_1.default.SymbolFlags.Function, // Before NamespaceModule
51
+ typescript_1.default.SymbolFlags.TypeAlias,
52
52
  typescript_1.default.SymbolFlags.Method,
53
53
  typescript_1.default.SymbolFlags.Interface,
54
54
  typescript_1.default.SymbolFlags.Property,
@@ -244,6 +244,12 @@ function convertFunctionOrMethod(context, symbol, exportSymbol) {
244
244
  // This will *NOT* be called for variables that look like functions, they need a special case.
245
245
  const isMethod = !!(symbol.flags &
246
246
  (typescript_1.default.SymbolFlags.Property | typescript_1.default.SymbolFlags.Method));
247
+ if (!isMethod) {
248
+ const comment = context.getComment(symbol, models_1.ReflectionKind.Function);
249
+ if (comment?.hasModifier("@class")) {
250
+ return convertSymbolAsClass(context, symbol, exportSymbol);
251
+ }
252
+ }
247
253
  const declarations = symbol.getDeclarations()?.filter(typescript_1.default.isFunctionLike) ?? [];
248
254
  // Don't do anything if we inherited this method and it is private.
249
255
  if (isMethod &&
@@ -276,8 +282,7 @@ function convertFunctionOrMethod(context, symbol, exportSymbol) {
276
282
  for (const sig of signatures) {
277
283
  (0, signature_1.createSignature)(scope, models_1.ReflectionKind.CallSignature, sig, symbol);
278
284
  }
279
- convertFunctionProperties(scope, symbol, type);
280
- return typescript_1.default.SymbolFlags.NamespaceModule;
285
+ return convertFunctionProperties(scope, symbol, type);
281
286
  }
282
287
  // getDeclaredTypeOfSymbol gets the INSTANCE type
283
288
  // getTypeOfSymbolAtLocation gets the STATIC type
@@ -484,7 +489,11 @@ function convertVariable(context, symbol, exportSymbol) {
484
489
  if (comment?.hasModifier("@namespace")) {
485
490
  return convertVariableAsNamespace(context, symbol, exportSymbol);
486
491
  }
487
- if (type.getCallSignatures().length) {
492
+ if (comment?.hasModifier("@class")) {
493
+ return convertSymbolAsClass(context, symbol, exportSymbol);
494
+ }
495
+ if (type.getCallSignatures().length &&
496
+ !type.getConstructSignatures().length) {
488
497
  return convertVariableAsFunction(context, symbol, exportSymbol);
489
498
  }
490
499
  const reflection = context.createDeclarationReflection(context.scope.kindOf(models_1.ReflectionKind.VariableContainer)
@@ -557,8 +566,8 @@ function convertVariableAsFunction(context, symbol, exportSymbol) {
557
566
  for (const signature of type.getCallSignatures()) {
558
567
  (0, signature_1.createSignature)(reflectionContext, models_1.ReflectionKind.CallSignature, signature, symbol);
559
568
  }
560
- convertFunctionProperties(context.withScope(reflection), symbol, type);
561
- return typescript_1.default.SymbolFlags.Property | typescript_1.default.SymbolFlags.NamespaceModule;
569
+ return (convertFunctionProperties(context.withScope(reflection), symbol, type) |
570
+ typescript_1.default.SymbolFlags.Property);
562
571
  }
563
572
  function convertFunctionProperties(context, symbol, type) {
564
573
  // #2436/#2461: Functions created with Object.assign on a function likely have properties
@@ -573,7 +582,51 @@ function convertFunctionProperties(context, symbol, type) {
573
582
  ((0, enum_1.hasAllFlags)(symbol.flags, nsFlags) ||
574
583
  !(0, enum_1.hasAnyFlag)(symbol.flags, nsFlags))) {
575
584
  convertSymbols(context, type.getProperties());
585
+ return typescript_1.default.SymbolFlags.NamespaceModule;
576
586
  }
587
+ return typescript_1.default.SymbolFlags.None;
588
+ }
589
+ function convertSymbolAsClass(context, symbol, exportSymbol) {
590
+ const reflection = context.createDeclarationReflection(models_1.ReflectionKind.Class, symbol, exportSymbol);
591
+ const rc = context.withScope(reflection);
592
+ context.finalizeDeclarationReflection(reflection);
593
+ if (!symbol.valueDeclaration) {
594
+ context.logger.error(`No value declaration found when converting ${symbol.name} as a class`, symbol.declarations?.[0]);
595
+ return;
596
+ }
597
+ const type = context.checker.getTypeOfSymbolAtLocation(symbol, symbol.valueDeclaration);
598
+ rc.shouldBeStatic = true;
599
+ convertSymbols(rc,
600
+ // Prototype is implicitly this class, don't document it.
601
+ type.getProperties().filter((prop) => prop.name !== "prototype"));
602
+ for (const sig of type.getCallSignatures()) {
603
+ (0, signature_1.createSignature)(rc, models_1.ReflectionKind.CallSignature, sig, undefined);
604
+ }
605
+ rc.shouldBeStatic = false;
606
+ const ctors = type.getConstructSignatures();
607
+ if (ctors.length) {
608
+ const constructMember = rc.createDeclarationReflection(models_1.ReflectionKind.Constructor, ctors?.[0]?.declaration?.symbol, void 0, "constructor");
609
+ // Modifiers are the same for all constructors
610
+ if (ctors.length && ctors[0].declaration) {
611
+ setModifiers(symbol, ctors[0].declaration, constructMember);
612
+ }
613
+ context.finalizeDeclarationReflection(constructMember);
614
+ const constructContext = rc.withScope(constructMember);
615
+ for (const sig of ctors) {
616
+ (0, signature_1.createConstructSignatureWithType)(constructContext, sig, reflection);
617
+ }
618
+ const instType = ctors[0].getReturnType();
619
+ convertSymbols(rc, instType.getProperties());
620
+ for (const sig of instType.getCallSignatures()) {
621
+ (0, signature_1.createSignature)(rc, models_1.ReflectionKind.CallSignature, sig, undefined);
622
+ }
623
+ }
624
+ else {
625
+ context.logger.warn(`${reflection.getFriendlyFullName()} is being converted as a class, but does not have any construct signatures`, symbol.valueDeclaration);
626
+ }
627
+ return (typescript_1.default.SymbolFlags.TypeAlias |
628
+ typescript_1.default.SymbolFlags.Interface |
629
+ typescript_1.default.SymbolFlags.Namespace);
577
630
  }
578
631
  function convertAccessor(context, symbol, exportSymbol) {
579
632
  const reflection = context.createDeclarationReflection(models_1.ReflectionKind.Accessor, symbol, exportSymbol);
@@ -87,10 +87,7 @@ function convertType(context, typeOrNode) {
87
87
  // We need to check it here, not just in the union checker, because typeToTypeNode
88
88
  // will use the origin when serializing
89
89
  // aliasSymbol check is important - #2468
90
- if (typeOrNode.isUnion() &&
91
- typeOrNode.origin &&
92
- !typeOrNode.origin.isUnion() &&
93
- !typeOrNode.aliasSymbol) {
90
+ if (typeOrNode.isUnion() && typeOrNode.origin && !typeOrNode.aliasSymbol) {
94
91
  return convertType(context, typeOrNode.origin);
95
92
  }
96
93
  // IgnoreErrors is important, without it, we can't assert that we will get a node.
@@ -1,4 +1,4 @@
1
- import type { DeclarationReflection } from ".";
1
+ import type { CommentDisplayPart, DeclarationReflection } from ".";
2
2
  import type { Serializer, JSONOutput, Deserializer } from "../serialization";
3
3
  /**
4
4
  * A category of reflections.
@@ -12,6 +12,10 @@ export declare class ReflectionCategory {
12
12
  * The title, a string representation of this category.
13
13
  */
14
14
  title: string;
15
+ /**
16
+ * The user specified description, if any, set with `@categoryDescription`
17
+ */
18
+ description?: CommentDisplayPart[];
15
19
  /**
16
20
  * All reflections of this category.
17
21
  */
@@ -26,6 +30,6 @@ export declare class ReflectionCategory {
26
30
  * Do all children of this category have a separate document?
27
31
  */
28
32
  allChildrenHaveOwnDocument(): boolean;
29
- toObject(_serializer: Serializer): JSONOutput.ReflectionCategory;
33
+ toObject(serializer: Serializer): JSONOutput.ReflectionCategory;
30
34
  fromObject(de: Deserializer, obj: JSONOutput.ReflectionCategory): void;
31
35
  }
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ReflectionCategory = void 0;
4
+ const comments_1 = require("./comments");
4
5
  /**
5
6
  * A category of reflections.
6
7
  *
@@ -27,15 +28,21 @@ class ReflectionCategory {
27
28
  allChildrenHaveOwnDocument() {
28
29
  return this.children.every((child) => child.hasOwnDocument);
29
30
  }
30
- toObject(_serializer) {
31
+ toObject(serializer) {
31
32
  return {
32
33
  title: this.title,
34
+ description: this.description
35
+ ? comments_1.Comment.serializeDisplayParts(serializer, this.description)
36
+ : undefined,
33
37
  children: this.children.length > 0
34
38
  ? this.children.map((child) => child.id)
35
39
  : undefined,
36
40
  };
37
41
  }
38
42
  fromObject(de, obj) {
43
+ if (obj.description) {
44
+ this.description = comments_1.Comment.deserializeDisplayParts(de, obj.description);
45
+ }
39
46
  if (obj.children) {
40
47
  de.defer((project) => {
41
48
  for (const childId of obj.children || []) {
@@ -1,5 +1,5 @@
1
1
  import { ReflectionCategory } from "./ReflectionCategory";
2
- import type { DeclarationReflection, Reflection } from ".";
2
+ import type { CommentDisplayPart, DeclarationReflection, Reflection } from ".";
3
3
  import type { Serializer, JSONOutput, Deserializer } from "../serialization";
4
4
  /**
5
5
  * A group of reflections. All reflections in a group are of the same kind.
@@ -14,6 +14,10 @@ export declare class ReflectionGroup {
14
14
  * The title, a string representation of the typescript kind, of this group.
15
15
  */
16
16
  title: string;
17
+ /**
18
+ * User specified description via `@groupDescription`, if specified.
19
+ */
20
+ description?: CommentDisplayPart[];
17
21
  /**
18
22
  * All reflections of this group.
19
23
  */
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ReflectionGroup = void 0;
4
4
  const ReflectionCategory_1 = require("./ReflectionCategory");
5
+ const comments_1 = require("./comments");
5
6
  /**
6
7
  * A group of reflections. All reflections in a group are of the same kind.
7
8
  *
@@ -33,6 +34,9 @@ class ReflectionGroup {
33
34
  toObject(serializer) {
34
35
  return {
35
36
  title: this.title,
37
+ description: this.description
38
+ ? comments_1.Comment.serializeDisplayParts(serializer, this.description)
39
+ : undefined,
36
40
  children: this.children.length > 0
37
41
  ? this.children.map((child) => child.id)
38
42
  : undefined,
@@ -40,6 +44,9 @@ class ReflectionGroup {
40
44
  };
41
45
  }
42
46
  fromObject(de, obj) {
47
+ if (obj.description) {
48
+ this.description = comments_1.Comment.deserializeDisplayParts(de, obj.description);
49
+ }
43
50
  if (obj.categories) {
44
51
  this.categories = obj.categories.map((catObj) => {
45
52
  const cat = new ReflectionCategory_1.ReflectionCategory(catObj.title);
@@ -76,7 +76,7 @@ export declare class Comment {
76
76
  /**
77
77
  * Helper utility to clone {@link Comment.summary} or {@link CommentTag.content}
78
78
  */
79
- static cloneDisplayParts(parts: CommentDisplayPart[]): ({
79
+ static cloneDisplayParts(parts: readonly CommentDisplayPart[]): ({
80
80
  kind: "text";
81
81
  text: string;
82
82
  } | {
@@ -93,6 +93,15 @@ export declare class Comment {
93
93
  /** @hidden no point in showing this signature in api docs */
94
94
  static serializeDisplayParts(serializer: Serializer, parts: CommentDisplayPart[] | undefined): JSONOutput.CommentDisplayPart[] | undefined;
95
95
  static deserializeDisplayParts(de: Deserializer, parts: JSONOutput.CommentDisplayPart[]): CommentDisplayPart[];
96
+ /**
97
+ * Splits the provided parts into a header (first line, as a string)
98
+ * and body (remaining lines). If the header line contains inline tags
99
+ * they will be serialized to a string.
100
+ */
101
+ static splitPartsToHeaderAndBody(parts: readonly CommentDisplayPart[]): {
102
+ header: string;
103
+ body: CommentDisplayPart[];
104
+ };
96
105
  /**
97
106
  * The content of the comment which is not associated with a block tag.
98
107
  */