typedoc 0.27.0-beta.0 → 0.27.0-beta.2

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 (58) hide show
  1. package/dist/lib/application.d.ts +1 -1
  2. package/dist/lib/application.js +2 -5
  3. package/dist/lib/converter/converter.js +2 -1
  4. package/dist/lib/converter/factories/index-signature.d.ts +2 -2
  5. package/dist/lib/converter/factories/index-signature.js +39 -16
  6. package/dist/lib/converter/plugins/MergeModuleWithPlugin.js +1 -1
  7. package/dist/lib/converter/symbols.js +11 -3
  8. package/dist/lib/converter/types.js +3 -4
  9. package/dist/lib/internationalization/locales/en.cjs +9 -3
  10. package/dist/lib/internationalization/locales/en.d.cts +7 -3
  11. package/dist/lib/internationalization/locales/jp.cjs +5 -3
  12. package/dist/lib/internationalization/locales/jp.d.cts +0 -3
  13. package/dist/lib/internationalization/locales/ko.cjs +5 -2
  14. package/dist/lib/internationalization/locales/ko.d.cts +0 -2
  15. package/dist/lib/internationalization/locales/zh.cjs +40 -13
  16. package/dist/lib/internationalization/locales/zh.d.cts +35 -7
  17. package/dist/lib/models/types.d.ts +3 -3
  18. package/dist/lib/output/formatter.js +6 -1
  19. package/dist/lib/output/output.d.ts +2 -1
  20. package/dist/lib/output/output.js +30 -11
  21. package/dist/lib/output/plugins/AssetsPlugin.d.ts +2 -0
  22. package/dist/lib/output/plugins/AssetsPlugin.js +2 -0
  23. package/dist/lib/output/plugins/HierarchyPlugin.d.ts +7 -0
  24. package/dist/lib/output/plugins/HierarchyPlugin.js +67 -0
  25. package/dist/lib/output/plugins/index.d.ts +1 -0
  26. package/dist/lib/output/plugins/index.js +1 -0
  27. package/dist/lib/output/renderer.js +2 -1
  28. package/dist/lib/output/themes/MarkedPlugin.d.ts +1 -1
  29. package/dist/lib/output/themes/default/DefaultTheme.js +1 -1
  30. package/dist/lib/output/themes/default/DefaultThemeRenderContext.d.ts +1 -1
  31. package/dist/lib/output/themes/default/layouts/default.js +3 -2
  32. package/dist/lib/output/themes/default/partials/comment.js +1 -1
  33. package/dist/lib/output/themes/default/partials/hierarchy.d.ts +1 -1
  34. package/dist/lib/output/themes/default/partials/hierarchy.js +9 -9
  35. package/dist/lib/output/themes/default/partials/navigation.js +1 -1
  36. package/dist/lib/output/themes/default/partials/toolbar.js +1 -1
  37. package/dist/lib/output/themes/default/partials/typeDetails.js +1 -0
  38. package/dist/lib/output/themes/default/templates/hierarchy.js +18 -13
  39. package/dist/lib/output/themes/default/templates/reflection.js +1 -0
  40. package/dist/lib/output/themes/lib.js +8 -1
  41. package/dist/lib/utils/entry-point.d.ts +1 -1
  42. package/dist/lib/utils/entry-point.js +4 -25
  43. package/dist/lib/utils/fs.d.ts +10 -0
  44. package/dist/lib/utils/fs.js +134 -20
  45. package/dist/lib/utils/general.d.ts +1 -0
  46. package/dist/lib/utils/general.js +4 -0
  47. package/dist/lib/utils/highlighter.d.ts +2 -3
  48. package/dist/lib/utils/highlighter.js +28 -30
  49. package/dist/lib/utils/jsx.d.ts +1 -2
  50. package/dist/lib/utils/jsx.elements.d.ts +1 -1
  51. package/dist/lib/utils/jsx.elements.js +3 -1
  52. package/dist/lib/utils/jsx.js +37 -40
  53. package/dist/lib/utils/options/declaration.d.ts +3 -1
  54. package/dist/lib/utils/options/defaults.d.ts +1 -1
  55. package/dist/lib/utils/options/sources/typedoc.js +13 -1
  56. package/package.json +9 -10
  57. package/static/main.js +4 -4
  58. package/static/style.css +18 -15
@@ -102,7 +102,12 @@ export function renderName(refl) {
102
102
  }
103
103
  return wbr(refl.name);
104
104
  }
105
+ // This is cached to avoid slowness with large projects.
106
+ const rootsCache = new WeakMap();
105
107
  export function getHierarchyRoots(project) {
108
+ const cached = rootsCache.get(project);
109
+ if (cached)
110
+ return cached;
106
111
  const allClasses = project.getReflectionsByKind(ReflectionKind.ClassOrInterface);
107
112
  const roots = allClasses.filter((refl) => {
108
113
  // If nobody extends this class, there's no possible hierarchy to display.
@@ -122,7 +127,9 @@ export function getHierarchyRoots(project) {
122
127
  },
123
128
  }));
124
129
  });
125
- return roots.sort((a, b) => a.name.localeCompare(b.name));
130
+ const result = roots.sort((a, b) => a.name.localeCompare(b.name));
131
+ rootsCache.set(project, result);
132
+ return result;
126
133
  }
127
134
  export function getMemberSections(parent, childFilter = () => true) {
128
135
  if (parent.categories?.length) {
@@ -36,7 +36,7 @@ export interface DocumentEntryPoint {
36
36
  displayName: string;
37
37
  path: string;
38
38
  }
39
- export declare function inferEntryPoints(logger: Logger, options: Options): Promise<DocumentationEntryPoint[]>;
39
+ export declare function inferEntryPoints(logger: Logger, options: Options): DocumentationEntryPoint[];
40
40
  export declare function getEntryPoints(logger: Logger, options: Options): DocumentationEntryPoint[] | undefined;
41
41
  /**
42
42
  * Document entry points are markdown documents that the user has requested we include in the project with
@@ -1,12 +1,10 @@
1
- import { dirname, join, relative, resolve } from "path";
1
+ import { join, relative, resolve } from "path";
2
2
  import ts from "typescript";
3
3
  import * as FS from "fs";
4
4
  import { expandPackages } from "./package-manifest.js";
5
5
  import { createMinimatch, matchesAny, nicePath, normalizePath, } from "./paths.js";
6
- import { deriveRootDir, discoverPackageJson, getCommonDirectory, glob, isDir, } from "./fs.js";
6
+ import { deriveRootDir, discoverPackageJson, getCommonDirectory, glob, inferPackageEntryPointPaths, isDir, } from "./fs.js";
7
7
  import { assertNever } from "./general.js";
8
- import { resolveAllExports } from "resolve-import/resolve-all-exports";
9
- import { fileURLToPath } from "url";
10
8
  /**
11
9
  * Defines how entry points are interpreted.
12
10
  * @enum
@@ -32,32 +30,13 @@ export const EntryPointStrategy = {
32
30
  */
33
31
  Merge: "merge",
34
32
  };
35
- export async function inferEntryPoints(logger, options) {
33
+ export function inferEntryPoints(logger, options) {
36
34
  const packageJson = discoverPackageJson(process.cwd());
37
35
  if (!packageJson) {
38
36
  logger.warn(logger.i18n.no_entry_points_provided());
39
37
  return [];
40
38
  }
41
- const entries = await resolveAllExports(packageJson.file, {
42
- conditions: ["typedoc", "import", "node"],
43
- });
44
- const pathEntries = Object.entries(entries).map(([k, v]) => {
45
- if (typeof v === "object") {
46
- return [k, fileURLToPath(v)];
47
- }
48
- return [k, v];
49
- });
50
- // resolveAllExports doesn't create a fake export for "main"
51
- // so do that here if we don't have any exports.
52
- if (pathEntries.length === 0) {
53
- if ("main" in packageJson.content &&
54
- typeof packageJson.content["main"] === "string") {
55
- pathEntries.push([
56
- ".",
57
- resolve(dirname(packageJson.file), packageJson.content["main"]),
58
- ]);
59
- }
60
- }
39
+ const pathEntries = inferPackageEntryPointPaths(packageJson.file);
61
40
  const entryPoints = [];
62
41
  const programs = getEntryPrograms(pathEntries.map((p) => p[1]), logger, options);
63
42
  // See also: addInferredDeclarationMapPaths in ReflectionSymbolId
@@ -35,6 +35,15 @@ export declare function writeFile(fileName: string, data: string): Promise<void>
35
35
  */
36
36
  export declare function copy(src: string, dest: string): Promise<void>;
37
37
  export declare function copySync(src: string, dest: string): void;
38
+ export interface DiscoverFilesController {
39
+ shouldRecurse(childPath: string[]): boolean;
40
+ matches(path: string): boolean;
41
+ /** Defaults to false */
42
+ matchDirectories?: boolean;
43
+ /** Defaults to false */
44
+ followSymlinks?: boolean;
45
+ }
46
+ export declare function discoverFiles(rootDir: string, controller: DiscoverFilesController): string[];
38
47
  /**
39
48
  * Simpler version of `glob.sync` that only covers our use cases, always ignoring node_modules.
40
49
  */
@@ -61,3 +70,4 @@ export declare function discoverPackageJson(dir: string): {
61
70
  };
62
71
  } | undefined;
63
72
  export declare function findPackageForPath(sourcePath: string): string | undefined;
73
+ export declare function inferPackageEntryPointPaths(packagePath: string): [importPath: string, resolvedPath: string][];
@@ -5,6 +5,8 @@ import { dirname, join, relative, resolve } from "path";
5
5
  import { optional, validate } from "./validation.js";
6
6
  import { createMinimatch, normalizePath } from "./paths.js";
7
7
  import { filterMap } from "./array.js";
8
+ import { escapeRegExp } from "./general.js";
9
+ import { ok } from "assert";
8
10
  export function isFile(file) {
9
11
  try {
10
12
  return fs.statSync(file).isFile();
@@ -144,33 +146,24 @@ export function copySync(src, dest) {
144
146
  // Do nothing for FIFO, special devices.
145
147
  }
146
148
  }
147
- /**
148
- * Simpler version of `glob.sync` that only covers our use cases, always ignoring node_modules.
149
- */
150
- export function glob(pattern, root, options = {}) {
149
+ // cache of fs.realpathSync results to avoid extra I/O
150
+ const realpathCache = new Map();
151
+ export function discoverFiles(rootDir, controller) {
151
152
  const result = [];
152
- const mini = new Minimatch(normalizePath(pattern));
153
- const dirs = [normalizePath(root).split("/")];
153
+ const dirs = [normalizePath(rootDir).split("/")];
154
154
  // cache of real paths to avoid infinite recursion
155
155
  const symlinkTargetsSeen = new Set();
156
- // cache of fs.realpathSync results to avoid extra I/O
157
- const realpathCache = new Map();
158
- const { includeDirectories = false, followSymlinks = false } = options;
159
- // if we _specifically asked_ for something in node_modules, fine, otherwise ignore it
160
- // to avoid globs like '**/*.ts' finding all the .d.ts files in node_modules.
161
- // however, if the pattern is something like `!**/node_modules/**`, this will also
162
- // cause node_modules to be considered, though it will be discarded by minimatch.
163
- const shouldIncludeNodeModules = pattern.includes("node_modules");
156
+ const { matchDirectories = false, followSymlinks = false } = controller;
164
157
  let dir = dirs.shift();
165
158
  const handleFile = (path) => {
166
159
  const childPath = [...dir, path].join("/");
167
- if (mini.match(childPath)) {
160
+ if (controller.matches(childPath)) {
168
161
  result.push(childPath);
169
162
  }
170
163
  };
171
164
  const handleDirectory = (path) => {
172
165
  const childPath = [...dir, path];
173
- if (mini.set.some((row) => mini.matchOne(childPath, row, /* partial */ true))) {
166
+ if (controller.shouldRecurse(childPath)) {
174
167
  dirs.push(childPath);
175
168
  }
176
169
  };
@@ -212,7 +205,7 @@ export function glob(pattern, root, options = {}) {
212
205
  }
213
206
  };
214
207
  while (dir) {
215
- if (includeDirectories && mini.match(dir.join("/"))) {
208
+ if (matchDirectories && controller.matches(dir.join("/"))) {
216
209
  result.push(dir.join("/"));
217
210
  }
218
211
  for (const child of fs.readdirSync(dir.join("/"), {
@@ -222,9 +215,7 @@ export function glob(pattern, root, options = {}) {
222
215
  handleFile(child.name);
223
216
  }
224
217
  else if (child.isDirectory()) {
225
- if (shouldIncludeNodeModules || child.name !== "node_modules") {
226
- handleDirectory(child.name);
227
- }
218
+ handleDirectory(child.name);
228
219
  }
229
220
  else if (followSymlinks && child.isSymbolicLink()) {
230
221
  handleSymlink(child.name);
@@ -234,6 +225,32 @@ export function glob(pattern, root, options = {}) {
234
225
  }
235
226
  return result;
236
227
  }
228
+ /**
229
+ * Simpler version of `glob.sync` that only covers our use cases, always ignoring node_modules.
230
+ */
231
+ export function glob(pattern, root, options = {}) {
232
+ const mini = new Minimatch(normalizePath(pattern));
233
+ const shouldIncludeNodeModules = pattern.includes("node_modules");
234
+ const controller = {
235
+ matches(path) {
236
+ return mini.match(path);
237
+ },
238
+ shouldRecurse(childPath) {
239
+ // if we _specifically asked_ for something in node_modules, fine, otherwise ignore it
240
+ // to avoid globs like '**/*.ts' finding all the .d.ts files in node_modules.
241
+ // however, if the pattern is something like `!**/node_modules/**`, this will also
242
+ // cause node_modules to be considered, though it will be discarded by minimatch.
243
+ if (childPath[childPath.length - 1] === "node_modules" &&
244
+ !shouldIncludeNodeModules) {
245
+ return false;
246
+ }
247
+ return mini.set.some((row) => mini.matchOne(childPath, row, /* partial */ true));
248
+ },
249
+ matchDirectories: options.includeDirectories,
250
+ followSymlinks: options.followSymlinks,
251
+ };
252
+ return discoverFiles(root, controller);
253
+ }
237
254
  export function hasTsExtension(path) {
238
255
  return /\.[cm]?ts$|\.tsx$/.test(path);
239
256
  }
@@ -311,3 +328,100 @@ export function findPackageForPath(sourcePath) {
311
328
  return packageJson.content.name;
312
329
  }
313
330
  }
331
+ export function inferPackageEntryPointPaths(packagePath) {
332
+ const packageDir = dirname(packagePath);
333
+ const packageJson = JSON.parse(readFile(packagePath));
334
+ const exports = packageJson.exports;
335
+ if (typeof exports === "string") {
336
+ return resolveExport(packageDir, ".", exports, false);
337
+ }
338
+ if (!exports || typeof exports !== "object") {
339
+ if (typeof packageJson.main === "string") {
340
+ return [[".", resolve(packageDir, packageJson.main)]];
341
+ }
342
+ return [];
343
+ }
344
+ const results = [];
345
+ if (Array.isArray(exports)) {
346
+ results.push(...resolveExport(packageDir, ".", exports, true));
347
+ }
348
+ else {
349
+ for (const [importPath, exp] of Object.entries(exports)) {
350
+ results.push(...resolveExport(packageDir, importPath, exp, false));
351
+ }
352
+ }
353
+ return results;
354
+ }
355
+ function resolveExport(packageDir, name, exportDeclaration, validatePath) {
356
+ if (typeof exportDeclaration === "string") {
357
+ return resolveStarredExport(packageDir, name, exportDeclaration, validatePath);
358
+ }
359
+ if (Array.isArray(exportDeclaration)) {
360
+ for (const item of exportDeclaration) {
361
+ const result = resolveExport(packageDir, name, item, true);
362
+ if (result.length) {
363
+ return result;
364
+ }
365
+ }
366
+ return [];
367
+ }
368
+ const EXPORT_CONDITIONS = ["typedoc", "types", "import", "node", "default"];
369
+ for (const cond in exportDeclaration) {
370
+ if (EXPORT_CONDITIONS.includes(cond)) {
371
+ return resolveExport(packageDir, name, exportDeclaration[cond], false);
372
+ }
373
+ }
374
+ // No recognized export condition
375
+ return [];
376
+ }
377
+ function isWildcardName(name) {
378
+ let starCount = 0;
379
+ for (let i = 0; i < name.length; ++i) {
380
+ if (name[i] === "*") {
381
+ ++starCount;
382
+ }
383
+ }
384
+ return starCount === 1;
385
+ }
386
+ function resolveStarredExport(packageDir, name, exportDeclaration, validatePath) {
387
+ // Wildcards only do something if there is exactly one star in the name
388
+ // If there isn't any star in the destination, all entries map to one file
389
+ // so don't bother enumerating possible files.
390
+ if (isWildcardName(name) && exportDeclaration.includes("*")) {
391
+ // Construct a pattern which we can use to determine if a wildcard matches
392
+ // This will look something like: /^/app\/package\/(.*).js$/
393
+ // The destination may have multiple wildcards, in which case they should
394
+ // contain the same text, so we replace "*" with backreferences for all
395
+ // but the first occurrence.
396
+ let first = true;
397
+ const matcher = new RegExp("^" +
398
+ escapeRegExp(normalizePath(packageDir) +
399
+ "/" +
400
+ exportDeclaration.replace(/^\.\//, "")).replaceAll("\\*", () => {
401
+ if (first) {
402
+ first = false;
403
+ return "(.*)";
404
+ }
405
+ return "\\1";
406
+ }) +
407
+ "$");
408
+ const matchedFiles = discoverFiles(packageDir, {
409
+ matches(path) {
410
+ return matcher.test(path);
411
+ },
412
+ shouldRecurse(path) {
413
+ return path[path.length - 1] !== "node_modules";
414
+ },
415
+ });
416
+ return matchedFiles.flatMap((path) => {
417
+ const starContent = path.match(matcher);
418
+ ok(starContent, "impossible, discoverFiles uses matcher");
419
+ return [[name.replace("*", starContent[1]), path]];
420
+ });
421
+ }
422
+ const exportPath = resolve(packageDir, exportDeclaration);
423
+ if (validatePath && !fs.existsSync(exportPath)) {
424
+ return [];
425
+ }
426
+ return [[name, exportPath]];
427
+ }
@@ -39,6 +39,7 @@ export type Chars<T extends string> = T extends `${infer C}${infer R}` ? C | Cha
39
39
  * Utility to help type checking ensure that there is no uncovered case.
40
40
  */
41
41
  export declare function assertNever(x: never): never;
42
+ export declare function escapeRegExp(s: string): string;
42
43
  export declare function editDistance(s: string, t: string): number;
43
44
  export declare function getSimilarValues(values: Iterable<string>, compareTo: string): string[];
44
45
  export declare function NonEnumerable(_cls: unknown, context: ClassFieldDecoratorContext): void;
@@ -8,6 +8,10 @@ import { DefaultMap } from "./map.js";
8
8
  export function assertNever(x) {
9
9
  throw new Error(`Expected handling to cover all possible cases, but it didn't cover: ${Util.inspect(x)}`);
10
10
  }
11
+ // From MDN
12
+ export function escapeRegExp(s) {
13
+ return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string
14
+ }
11
15
  // Based on https://en.wikipedia.org/wiki/Levenshtein_distance#Iterative_with_two_matrix_rows
12
16
  // Slightly modified for improved match results for options
13
17
  export function editDistance(s, t) {
@@ -1,6 +1,5 @@
1
- import type { BundledLanguage, BundledTheme } from "shiki" with { "resolution-mode": "import" };
2
- export declare function loadShikiMetadata(): Promise<void>;
3
- export declare function loadHighlighter(lightTheme: BundledTheme, darkTheme: BundledTheme, langs: BundledLanguage[]): Promise<void>;
1
+ import * as shiki from "@gerrit0/mini-shiki";
2
+ export declare function loadHighlighter(lightTheme: shiki.BundledTheme, darkTheme: shiki.BundledTheme, langs: shiki.BundledLanguage[]): Promise<void>;
4
3
  export declare function isSupportedLanguage(lang: string): boolean;
5
4
  export declare function getSupportedLanguages(): string[];
6
5
  export declare function getSupportedLanguagesWithoutAliases(): string[];
@@ -1,31 +1,24 @@
1
- import { ok as assert, ok } from "assert";
1
+ import * as shiki from "@gerrit0/mini-shiki";
2
2
  import * as JSX from "./jsx.js";
3
3
  import { unique } from "./array.js";
4
+ import assert from "assert";
4
5
  const aliases = new Map();
5
- let supportedLanguagesWithoutAliases = [];
6
- let supportedLanguages = [];
7
- let supportedThemes = [];
8
- const plaintextLanguages = ["txt", "text"];
9
- export async function loadShikiMetadata() {
10
- if (aliases.size)
11
- return;
12
- const shiki = await import("shiki");
13
- for (const lang of shiki.bundledLanguagesInfo) {
14
- for (const alias of lang.aliases || []) {
15
- aliases.set(alias, lang.id);
16
- }
6
+ for (const lang of shiki.bundledLanguagesInfo) {
7
+ for (const alias of lang.aliases || []) {
8
+ aliases.set(alias, lang.id);
17
9
  }
18
- supportedLanguages = unique([
19
- ...plaintextLanguages,
20
- ...aliases.keys(),
21
- ...shiki.bundledLanguagesInfo.map((lang) => lang.id),
22
- ]).sort();
23
- supportedLanguagesWithoutAliases = unique([
24
- ...plaintextLanguages,
25
- ...shiki.bundledLanguagesInfo.map((lang) => lang.id),
26
- ]);
27
- supportedThemes = Object.keys(shiki.bundledThemes);
28
10
  }
11
+ const plaintextLanguages = ["txt", "text"];
12
+ const supportedLanguagesWithoutAliases = unique([
13
+ ...plaintextLanguages,
14
+ ...shiki.bundledLanguagesInfo.map((lang) => lang.id),
15
+ ]);
16
+ const supportedLanguages = unique([
17
+ ...plaintextLanguages,
18
+ ...aliases.keys(),
19
+ ...shiki.bundledLanguagesInfo.map((lang) => lang.id),
20
+ ]).sort();
21
+ const supportedThemes = Object.keys(shiki.bundledThemes);
29
22
  class DoubleHighlighter {
30
23
  highlighter;
31
24
  light;
@@ -40,7 +33,7 @@ class DoubleHighlighter {
40
33
  return this.highlighter.getLoadedLanguages().includes(lang);
41
34
  }
42
35
  highlight(code, lang) {
43
- const tokens = this.highlighter.codeToTokensWithThemes(code, {
36
+ const tokens = shiki.codeToTokensWithThemes(this.highlighter, code, {
44
37
  themes: { light: this.light, dark: this.dark },
45
38
  lang: lang,
46
39
  });
@@ -101,27 +94,32 @@ class DoubleHighlighter {
101
94
  return scheme;
102
95
  }
103
96
  }
97
+ let shikiEngine;
104
98
  let highlighter;
105
99
  export async function loadHighlighter(lightTheme, darkTheme, langs) {
106
100
  if (highlighter)
107
101
  return;
108
- const shiki = await import("shiki");
109
- const hl = await shiki.createHighlighter({ themes: [lightTheme, darkTheme], langs });
102
+ if (!shikiEngine) {
103
+ await shiki.loadBuiltinWasm();
104
+ shikiEngine = await shiki.createOnigurumaEngine();
105
+ }
106
+ const hl = await shiki.createShikiInternal({
107
+ engine: shikiEngine,
108
+ themes: [shiki.bundledThemes[lightTheme], shiki.bundledThemes[darkTheme]],
109
+ langs: langs.map((lang) => shiki.bundledLanguages[lang]),
110
+ });
110
111
  highlighter = new DoubleHighlighter(hl, lightTheme, darkTheme);
111
112
  }
112
113
  export function isSupportedLanguage(lang) {
113
114
  return getSupportedLanguages().includes(lang);
114
115
  }
115
116
  export function getSupportedLanguages() {
116
- ok(supportedLanguages.length > 0, "loadShikiMetadata has not been called");
117
117
  return supportedLanguages;
118
118
  }
119
119
  export function getSupportedLanguagesWithoutAliases() {
120
- ok(supportedLanguagesWithoutAliases.length > 0, "loadShikiMetadata has not been called");
121
- return supportedLanguages;
120
+ return supportedLanguagesWithoutAliases;
122
121
  }
123
122
  export function getSupportedThemes() {
124
- ok(supportedThemes.length > 0, "loadShikiMetadata has not been called");
125
123
  return supportedThemes;
126
124
  }
127
125
  export function isLoadedLanguage(lang) {
@@ -14,7 +14,6 @@
14
14
  * @module
15
15
  */
16
16
  import type { IntrinsicElements, JsxElement, JsxChildren, JsxComponent } from "./jsx.elements.js";
17
- import { JsxFragment as Fragment } from "./jsx.elements.js";
18
17
  export type { JsxElement as Element, JsxChildren as Children, JsxComponent, } from "./jsx.elements.js";
19
18
  export { JsxFragment as Fragment } from "./jsx.elements.js";
20
19
  /**
@@ -41,7 +40,7 @@ export declare namespace JSX {
41
40
  * @param props
42
41
  * @param children
43
42
  */
44
- export declare function createElement(tag: typeof Fragment | string | JsxComponent<any>, props: object | null, ...children: JsxChildren[]): JsxElement;
43
+ export declare function createElement(tag: string | JsxComponent<any>, props: object | null, ...children: JsxChildren[]): JsxElement;
45
44
  export declare function setRenderSettings(options: {
46
45
  pretty: boolean;
47
46
  }): void;
@@ -123,7 +123,7 @@ export interface IntrinsicElements {
123
123
  use: JsxUseElementProps;
124
124
  text: JsxTextElementProps;
125
125
  }
126
- export declare const JsxFragment: unique symbol;
126
+ export declare function JsxFragment(): never;
127
127
  export type JsxComponent<P> = (props: P) => JsxElement | null | undefined;
128
128
  export interface JsxElement {
129
129
  tag: typeof JsxFragment | string | JsxComponent<any>;
@@ -1 +1,3 @@
1
- export const JsxFragment = Symbol();
1
+ export function JsxFragment() {
2
+ throw new Error("Should never be called");
3
+ }
@@ -14,7 +14,7 @@
14
14
  * @module
15
15
  */
16
16
  import { escapeHtml } from "./html.js";
17
- import { JsxFragment as Fragment } from "./jsx.elements.js";
17
+ import { JsxFragment } from "./jsx.elements.js";
18
18
  export { JsxFragment as Fragment } from "./jsx.elements.js";
19
19
  /**
20
20
  * Used to inject HTML directly into the document.
@@ -75,57 +75,52 @@ export function renderElement(element) {
75
75
  return "";
76
76
  }
77
77
  const { tag, props, children } = element;
78
+ let html = "";
78
79
  if (typeof tag === "function") {
79
80
  if (tag === Raw) {
80
81
  return String(props.html);
81
82
  }
83
+ if (tag === JsxFragment) {
84
+ renderChildren(children);
85
+ return html;
86
+ }
82
87
  return renderElement(tag(Object.assign({ children }, props)));
83
88
  }
84
- let html = "";
85
- if (tag !== Fragment) {
86
- if (blockElements.has(tag) && renderPretty && html) {
87
- html += "\n";
88
- }
89
- html += "<";
90
- html += tag;
91
- for (const [key, val] of Object.entries(props ?? {})) {
92
- if (val == null)
93
- continue;
94
- if (typeof val == "boolean") {
95
- if (val) {
96
- html += " ";
97
- html += key;
98
- }
99
- }
100
- else {
89
+ if (blockElements.has(tag) && renderPretty && html) {
90
+ html += "\n";
91
+ }
92
+ html += "<";
93
+ html += tag;
94
+ for (const [key, val] of Object.entries(props ?? {})) {
95
+ if (val == null)
96
+ continue;
97
+ if (typeof val == "boolean") {
98
+ if (val) {
101
99
  html += " ";
102
100
  html += key;
103
- html += '="';
104
- html += (typeof val === "string" ? val : JSON.stringify(val)).replaceAll('"', "&quot;");
105
- html += '"';
106
101
  }
107
102
  }
103
+ else {
104
+ html += " ";
105
+ html += key;
106
+ html += '="';
107
+ html += (typeof val === "string" ? val : JSON.stringify(val)).replaceAll('"', "&quot;");
108
+ html += '"';
109
+ }
108
110
  }
109
- let hasChildren = false;
110
111
  if (children.length) {
111
- hasChildren = true;
112
- if (tag !== Fragment)
113
- html += ">";
112
+ html += ">";
114
113
  renderChildren(children);
114
+ html += "</";
115
+ html += tag;
116
+ html += ">";
115
117
  }
116
- if (tag !== Fragment) {
117
- if (!hasChildren) {
118
- if (voidElements.has(tag)) {
119
- html += "/>";
120
- }
121
- else {
122
- html += "></";
123
- html += tag;
124
- html += ">";
125
- }
118
+ else {
119
+ if (voidElements.has(tag)) {
120
+ html += "/>";
126
121
  }
127
122
  else {
128
- html += "</";
123
+ html += "></";
129
124
  html += tag;
130
125
  html += ">";
131
126
  }
@@ -157,19 +152,21 @@ export function renderElementToText(element) {
157
152
  return "";
158
153
  }
159
154
  const { tag, props, children } = element;
155
+ let html = "";
160
156
  if (typeof tag === "function") {
161
157
  if (tag === Raw) {
162
158
  return String(props.html);
163
159
  }
160
+ if (tag === JsxFragment) {
161
+ renderChildren(children);
162
+ return html;
163
+ }
164
164
  return renderElementToText(tag(Object.assign({ children }, props)));
165
165
  }
166
166
  else if (tag === "br") {
167
167
  return "\n";
168
168
  }
169
- let html = "";
170
- if (children.length) {
171
- renderChildren(children);
172
- }
169
+ renderChildren(children);
173
170
  return html;
174
171
  function renderChildren(children) {
175
172
  for (const child of children) {
@@ -1,4 +1,4 @@
1
- import type { BundledTheme as ShikiTheme } from "shiki" with { "resolution-mode": "import" };
1
+ import type { BundledTheme as ShikiTheme } from "@gerrit0/mini-shiki";
2
2
  import type { LogLevel } from "../loggers.js";
3
3
  import type { SortStrategy } from "../sort.js";
4
4
  import type { EntryPointStrategy } from "../entry-point.js";
@@ -97,6 +97,7 @@ export interface TypeDocOptionMap {
97
97
  readme: string;
98
98
  outputs: ManuallyValidatedOption<Array<OutputSpecification>>;
99
99
  out: string;
100
+ html: string;
100
101
  json: string;
101
102
  pretty: boolean;
102
103
  emit: typeof EmitStrategy;
@@ -160,6 +161,7 @@ export interface TypeDocOptionMap {
160
161
  sluggerConfiguration: {
161
162
  lowercase: boolean;
162
163
  };
164
+ includeHierarchySummary: boolean;
163
165
  visibilityFilters: ManuallyValidatedOption<{
164
166
  protected?: boolean;
165
167
  private?: boolean;
@@ -1,4 +1,4 @@
1
- import type { BundledLanguage } from "shiki" with { "resolution-mode": "import" };
1
+ import type { BundledLanguage } from "@gerrit0/mini-shiki";
2
2
  import type { EnumKeys } from "../enum.js";
3
3
  import type { ReflectionKind } from "../../models/index.js";
4
4
  /**
@@ -231,12 +231,18 @@ export function addTypeDocOptions(options) {
231
231
  });
232
232
  options.addDeclaration({
233
233
  name: "out",
234
- outputShortcut: "html",
235
234
  help: (i18n) => i18n.help_out(),
236
235
  type: ParameterType.Path,
237
236
  hint: ParameterHint.Directory,
238
237
  defaultValue: "./docs",
239
238
  });
239
+ options.addDeclaration({
240
+ name: "html",
241
+ outputShortcut: "html",
242
+ help: (i18n) => i18n.help_html(),
243
+ type: ParameterType.Path,
244
+ hint: ParameterHint.Directory,
245
+ });
240
246
  options.addDeclaration({
241
247
  name: "json",
242
248
  outputShortcut: "json",
@@ -538,6 +544,12 @@ export function addTypeDocOptions(options) {
538
544
  lowercase: true,
539
545
  },
540
546
  });
547
+ options.addDeclaration({
548
+ name: "includeHierarchySummary",
549
+ help: (i18n) => i18n.help_includeHierarchySummary(),
550
+ type: ParameterType.Boolean,
551
+ defaultValue: true,
552
+ });
541
553
  options.addDeclaration({
542
554
  name: "visibilityFilters",
543
555
  help: (i18n) => i18n.help_visibilityFilters(),