typedoc 0.25.7 → 0.25.9

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 (51) 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.d.ts +2 -0
  10. package/dist/lib/converter/converter.js +11 -2
  11. package/dist/lib/converter/factories/signature.d.ts +5 -1
  12. package/dist/lib/converter/factories/signature.js +25 -1
  13. package/dist/lib/converter/plugins/CategoryPlugin.js +19 -3
  14. package/dist/lib/converter/plugins/GroupPlugin.d.ts +2 -2
  15. package/dist/lib/converter/plugins/GroupPlugin.js +18 -2
  16. package/dist/lib/converter/plugins/LinkResolverPlugin.d.ts +1 -0
  17. package/dist/lib/converter/plugins/LinkResolverPlugin.js +24 -0
  18. package/dist/lib/converter/symbols.js +57 -4
  19. package/dist/lib/converter/types.js +24 -2
  20. package/dist/lib/models/ReflectionCategory.d.ts +6 -2
  21. package/dist/lib/models/ReflectionCategory.js +8 -1
  22. package/dist/lib/models/ReflectionGroup.d.ts +5 -1
  23. package/dist/lib/models/ReflectionGroup.js +7 -0
  24. package/dist/lib/models/comments/comment.d.ts +10 -1
  25. package/dist/lib/models/comments/comment.js +45 -0
  26. package/dist/lib/models/reflections/abstract.d.ts +1 -1
  27. package/dist/lib/models/reflections/abstract.js +6 -7
  28. package/dist/lib/models/reflections/declaration.js +4 -3
  29. package/dist/lib/models/reflections/project.js +5 -5
  30. package/dist/lib/output/plugins/SitemapPlugin.d.ts +7 -0
  31. package/dist/lib/output/plugins/SitemapPlugin.js +152 -0
  32. package/dist/lib/output/plugins/index.d.ts +1 -0
  33. package/dist/lib/output/plugins/index.js +3 -1
  34. package/dist/lib/output/themes/default/DefaultTheme.js +1 -13
  35. package/dist/lib/output/themes/default/partials/index.js +3 -1
  36. package/dist/lib/output/themes/default/partials/member.signature.body.js +1 -1
  37. package/dist/lib/output/themes/default/partials/typeParameters.js +1 -1
  38. package/dist/lib/output/themes/default/templates/hierarchy.d.ts +1 -1
  39. package/dist/lib/output/themes/default/templates/hierarchy.js +8 -9
  40. package/dist/lib/output/themes/lib.d.ts +2 -1
  41. package/dist/lib/output/themes/lib.js +24 -1
  42. package/dist/lib/serialization/schema.d.ts +3 -3
  43. package/dist/lib/utils/entry-point.js +1 -1
  44. package/dist/lib/utils/events.js +1 -0
  45. package/dist/lib/utils/options/declaration.d.ts +2 -0
  46. package/dist/lib/utils/options/sources/typedoc.js +15 -0
  47. package/dist/lib/utils/options/tsdoc-defaults.d.ts +2 -2
  48. package/dist/lib/utils/options/tsdoc-defaults.js +4 -1
  49. package/package.json +3 -3
  50. package/static/main.js +4 -4
  51. 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
  }
@@ -38,6 +38,8 @@ export declare class Converter extends ChildableComponent<Application, Converter
38
38
  accessor useTsLinkResolution: boolean;
39
39
  /** @internal */
40
40
  accessor preserveLinkText: boolean;
41
+ /** @internal */
42
+ accessor maxTypeConversionDepth: number;
41
43
  private _config?;
42
44
  private _externalSymbolResolvers;
43
45
  get config(): CommentParserConfig;
@@ -71,7 +71,7 @@ const linkResolver_1 = require("./comments/linkResolver");
71
71
  * Compiles source files using TypeScript and converts compiler symbols to reflections.
72
72
  */
73
73
  let Converter = (() => {
74
- var _Converter_externalPattern_accessor_storage, _Converter_excludeExternals_accessor_storage, _Converter_excludeNotDocumented_accessor_storage, _Converter_excludePrivate_accessor_storage, _Converter_excludeProtected_accessor_storage, _Converter_excludeReferences_accessor_storage, _Converter_commentStyle_accessor_storage, _Converter_validation_accessor_storage, _Converter_externalSymbolLinkMappings_accessor_storage, _Converter_useTsLinkResolution_accessor_storage, _Converter_preserveLinkText_accessor_storage;
74
+ var _Converter_externalPattern_accessor_storage, _Converter_excludeExternals_accessor_storage, _Converter_excludeNotDocumented_accessor_storage, _Converter_excludePrivate_accessor_storage, _Converter_excludeProtected_accessor_storage, _Converter_excludeReferences_accessor_storage, _Converter_commentStyle_accessor_storage, _Converter_validation_accessor_storage, _Converter_externalSymbolLinkMappings_accessor_storage, _Converter_useTsLinkResolution_accessor_storage, _Converter_preserveLinkText_accessor_storage, _Converter_maxTypeConversionDepth_accessor_storage;
75
75
  let _classDecorators = [(0, component_1.Component)({
76
76
  name: "converter",
77
77
  internal: true,
@@ -104,6 +104,8 @@ let Converter = (() => {
104
104
  let _useTsLinkResolution_initializers = [];
105
105
  let _preserveLinkText_decorators;
106
106
  let _preserveLinkText_initializers = [];
107
+ let _maxTypeConversionDepth_decorators;
108
+ let _maxTypeConversionDepth_initializers = [];
107
109
  var Converter = _classThis = class extends _classSuper {
108
110
  /** @internal */
109
111
  get externalPattern() { return __classPrivateFieldGet(this, _Converter_externalPattern_accessor_storage, "f"); }
@@ -138,6 +140,9 @@ let Converter = (() => {
138
140
  /** @internal */
139
141
  get preserveLinkText() { return __classPrivateFieldGet(this, _Converter_preserveLinkText_accessor_storage, "f"); }
140
142
  set preserveLinkText(value) { __classPrivateFieldSet(this, _Converter_preserveLinkText_accessor_storage, value, "f"); }
143
+ /** @internal */
144
+ get maxTypeConversionDepth() { return __classPrivateFieldGet(this, _Converter_maxTypeConversionDepth_accessor_storage, "f"); }
145
+ set maxTypeConversionDepth(value) { __classPrivateFieldSet(this, _Converter_maxTypeConversionDepth_accessor_storage, value, "f"); }
141
146
  get config() {
142
147
  return this._config || this._buildCommentParserConfig();
143
148
  }
@@ -154,6 +159,7 @@ let Converter = (() => {
154
159
  _Converter_externalSymbolLinkMappings_accessor_storage.set(this, __runInitializers(this, _externalSymbolLinkMappings_initializers, void 0));
155
160
  _Converter_useTsLinkResolution_accessor_storage.set(this, __runInitializers(this, _useTsLinkResolution_initializers, void 0));
156
161
  _Converter_preserveLinkText_accessor_storage.set(this, __runInitializers(this, _preserveLinkText_initializers, void 0));
162
+ _Converter_maxTypeConversionDepth_accessor_storage.set(this, __runInitializers(this, _maxTypeConversionDepth_initializers, void 0));
157
163
  this._externalSymbolResolvers = [];
158
164
  this.addUnknownSymbolResolver((ref) => {
159
165
  // Require global links, matching local ones will likely hide mistakes where the
@@ -184,7 +190,7 @@ let Converter = (() => {
184
190
  * Compile the given source files and create a project reflection for them.
185
191
  */
186
192
  convert(entryPoints) {
187
- const programs = entryPoints.map((e) => e.program);
193
+ const programs = (0, utils_1.unique)(entryPoints.map((e) => e.program));
188
194
  this.externalPatternCache = void 0;
189
195
  const project = new index_1.ProjectReflection(this.application.options.getValue("name"));
190
196
  const context = new context_1.Context(this, programs, project);
@@ -378,6 +384,7 @@ let Converter = (() => {
378
384
  _Converter_externalSymbolLinkMappings_accessor_storage = new WeakMap();
379
385
  _Converter_useTsLinkResolution_accessor_storage = new WeakMap();
380
386
  _Converter_preserveLinkText_accessor_storage = new WeakMap();
387
+ _Converter_maxTypeConversionDepth_accessor_storage = new WeakMap();
381
388
  __setFunctionName(_classThis, "Converter");
382
389
  (() => {
383
390
  const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
@@ -392,6 +399,7 @@ let Converter = (() => {
392
399
  _externalSymbolLinkMappings_decorators = [(0, utils_1.Option)("externalSymbolLinkMappings")];
393
400
  _useTsLinkResolution_decorators = [(0, utils_1.Option)("useTsLinkResolution")];
394
401
  _preserveLinkText_decorators = [(0, utils_1.Option)("preserveLinkText")];
402
+ _maxTypeConversionDepth_decorators = [(0, utils_1.Option)("maxTypeConversionDepth")];
395
403
  __esDecorate(_classThis, null, _externalPattern_decorators, { kind: "accessor", name: "externalPattern", static: false, private: false, access: { has: obj => "externalPattern" in obj, get: obj => obj.externalPattern, set: (obj, value) => { obj.externalPattern = value; } }, metadata: _metadata }, _externalPattern_initializers, _instanceExtraInitializers);
396
404
  __esDecorate(_classThis, null, _excludeExternals_decorators, { kind: "accessor", name: "excludeExternals", static: false, private: false, access: { has: obj => "excludeExternals" in obj, get: obj => obj.excludeExternals, set: (obj, value) => { obj.excludeExternals = value; } }, metadata: _metadata }, _excludeExternals_initializers, _instanceExtraInitializers);
397
405
  __esDecorate(_classThis, null, _excludeNotDocumented_decorators, { kind: "accessor", name: "excludeNotDocumented", static: false, private: false, access: { has: obj => "excludeNotDocumented" in obj, get: obj => obj.excludeNotDocumented, set: (obj, value) => { obj.excludeNotDocumented = value; } }, metadata: _metadata }, _excludeNotDocumented_initializers, _instanceExtraInitializers);
@@ -403,6 +411,7 @@ let Converter = (() => {
403
411
  __esDecorate(_classThis, null, _externalSymbolLinkMappings_decorators, { kind: "accessor", name: "externalSymbolLinkMappings", static: false, private: false, access: { has: obj => "externalSymbolLinkMappings" in obj, get: obj => obj.externalSymbolLinkMappings, set: (obj, value) => { obj.externalSymbolLinkMappings = value; } }, metadata: _metadata }, _externalSymbolLinkMappings_initializers, _instanceExtraInitializers);
404
412
  __esDecorate(_classThis, null, _useTsLinkResolution_decorators, { kind: "accessor", name: "useTsLinkResolution", static: false, private: false, access: { has: obj => "useTsLinkResolution" in obj, get: obj => obj.useTsLinkResolution, set: (obj, value) => { obj.useTsLinkResolution = value; } }, metadata: _metadata }, _useTsLinkResolution_initializers, _instanceExtraInitializers);
405
413
  __esDecorate(_classThis, null, _preserveLinkText_decorators, { kind: "accessor", name: "preserveLinkText", static: false, private: false, access: { has: obj => "preserveLinkText" in obj, get: obj => obj.preserveLinkText, set: (obj, value) => { obj.preserveLinkText = value; } }, metadata: _metadata }, _preserveLinkText_initializers, _instanceExtraInitializers);
414
+ __esDecorate(_classThis, null, _maxTypeConversionDepth_decorators, { kind: "accessor", name: "maxTypeConversionDepth", static: false, private: false, access: { has: obj => "maxTypeConversionDepth" in obj, get: obj => obj.maxTypeConversionDepth, set: (obj, value) => { obj.maxTypeConversionDepth = value; } }, metadata: _metadata }, _maxTypeConversionDepth_initializers, _instanceExtraInitializers);
406
415
  __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
407
416
  Converter = _classThis = _classDescriptor.value;
408
417
  if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
@@ -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 &&
@@ -483,7 +489,11 @@ function convertVariable(context, symbol, exportSymbol) {
483
489
  if (comment?.hasModifier("@namespace")) {
484
490
  return convertVariableAsNamespace(context, symbol, exportSymbol);
485
491
  }
486
- 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) {
487
497
  return convertVariableAsFunction(context, symbol, exportSymbol);
488
498
  }
489
499
  const reflection = context.createDeclarationReflection(context.scope.kindOf(models_1.ReflectionKind.VariableContainer)
@@ -556,8 +566,8 @@ function convertVariableAsFunction(context, symbol, exportSymbol) {
556
566
  for (const signature of type.getCallSignatures()) {
557
567
  (0, signature_1.createSignature)(reflectionContext, models_1.ReflectionKind.CallSignature, signature, symbol);
558
568
  }
559
- convertFunctionProperties(context.withScope(reflection), symbol, type);
560
- 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);
561
571
  }
562
572
  function convertFunctionProperties(context, symbol, type) {
563
573
  // #2436/#2461: Functions created with Object.assign on a function likely have properties
@@ -574,6 +584,49 @@ function convertFunctionProperties(context, symbol, type) {
574
584
  convertSymbols(context, type.getProperties());
575
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);
@@ -71,15 +71,22 @@ function maybeConvertType(context, typeOrNode) {
71
71
  }
72
72
  return convertType(context, typeOrNode);
73
73
  }
74
+ let typeConversionDepth = 0;
74
75
  function convertType(context, typeOrNode) {
75
76
  if (!typeOrNode) {
76
77
  return new models_1.IntrinsicType("any");
77
78
  }
79
+ if (typeConversionDepth > context.converter.maxTypeConversionDepth) {
80
+ return new models_1.UnknownType("...");
81
+ }
78
82
  loadConverters();
79
83
  if ("kind" in typeOrNode) {
80
84
  const converter = converters.get(typeOrNode.kind);
81
85
  if (converter) {
82
- return converter.convert(context, typeOrNode);
86
+ ++typeConversionDepth;
87
+ const result = converter.convert(context, typeOrNode);
88
+ --typeConversionDepth;
89
+ return result;
83
90
  }
84
91
  return requestBugReport(context, typeOrNode);
85
92
  }
@@ -88,6 +95,7 @@ function convertType(context, typeOrNode) {
88
95
  // will use the origin when serializing
89
96
  // aliasSymbol check is important - #2468
90
97
  if (typeOrNode.isUnion() && typeOrNode.origin && !typeOrNode.aliasSymbol) {
98
+ // Don't increment typeConversionDepth as this is a transparent step to the user.
91
99
  return convertType(context, typeOrNode.origin);
92
100
  }
93
101
  // IgnoreErrors is important, without it, we can't assert that we will get a node.
@@ -106,7 +114,9 @@ function convertType(context, typeOrNode) {
106
114
  converter = typeLiteralConverter;
107
115
  }
108
116
  seenTypes.add(typeOrNode.id);
117
+ ++typeConversionDepth;
109
118
  const result = converter.convertType(context, typeOrNode, node);
119
+ --typeConversionDepth;
110
120
  seenTypes.delete(typeOrNode.id);
111
121
  return result;
112
122
  }
@@ -643,7 +653,9 @@ const unionConverter = {
643
653
  return new models_1.UnionType(node.types.map((type) => convertType(context, type)));
644
654
  },
645
655
  convertType(context, type) {
646
- return new models_1.UnionType(type.types.map((type) => convertType(context, type)));
656
+ const types = type.types.map((type) => convertType(context, type));
657
+ sortLiteralUnion(types);
658
+ return new models_1.UnionType(types);
647
659
  },
648
660
  };
649
661
  const jsDocNullableTypeConverter = {
@@ -695,3 +707,13 @@ function kindToModifier(kind) {
695
707
  return undefined;
696
708
  }
697
709
  }
710
+ function sortLiteralUnion(types) {
711
+ if (types.some((t) => t.type !== "literal" || typeof t.value !== "number")) {
712
+ return;
713
+ }
714
+ types.sort((a, b) => {
715
+ const aLit = a;
716
+ const bLit = b;
717
+ return aLit.value - bLit.value;
718
+ });
719
+ }
@@ -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 || []) {