UNPKG

typedoc

Version:

Create api documentation for TypeScript projects.

1,744 lines (1,725 loc) 230 kB
var __defProp = Object.defineProperty; var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, { get: (a, b) => (typeof require !== "undefined" ? require : a)[b] }) : x)(function(x) { if (typeof require !== "undefined") return require.apply(this, arguments); throw Error('Dynamic require of "' + x + '" is not supported'); }); var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; // src/lib/utils/component.ts import { EventDispatcher } from "#utils"; var AbstractComponent = class extends EventDispatcher { /** * The owner of this component instance. */ _componentOwner; /** * The name of this component as set by the `@Component` decorator. */ componentName; /** * Create new Component instance. */ constructor(owner) { super(); this._componentOwner = owner; } /** * Return the application / root component instance. */ get application() { if (this._componentOwner === null) { return this; } return this._componentOwner.application; } /** * Return the owner of this component. */ get owner() { return this._componentOwner === null ? this : this._componentOwner; } }; // src/lib/utils/fs.ts import * as fs from "fs"; import { promises as fsp } from "fs"; import { Minimatch as Minimatch2 } from "minimatch"; import { dirname as dirname2, join, relative as relative2, resolve as resolve2 } from "path"; import { escapeRegExp, Validation } from "#utils"; // src/lib/utils/paths.ts import { countMatches, filterMap } from "#utils"; import { Minimatch } from "minimatch"; import { dirname, isAbsolute, relative, resolve } from "path"; var MinimatchSet = class { patterns; constructor(patterns) { this.patterns = patterns.map((p) => new Minimatch(p, { dot: true })); } matchesAny(path) { return this.patterns.some((p) => { return p.match(path); }); } }; function escapeGlob(glob2) { return glob2.replace(/[?*()[\]\\{}]/g, "\\$&"); } function isGlobalGlob(glob2) { const start = glob2.match(/^[!#]+/)?.[0].length ?? 0; return glob2.startsWith("**", start); } function splitGlobToPathAndSpecial(glob2) { const modifiers = glob2.match(/^[!#]+/)?.[0] ?? ""; const noModifierGlob = glob2.substring(modifiers.length); if (isGlobalGlob(glob2)) { return { modifiers, path: "", glob: noModifierGlob }; } const mini = new Minimatch(noModifierGlob, { dot: true }); const basePaths = mini.set.map((set) => { const stop = set.findIndex((part) => typeof part !== "string"); if (stop === -1) { return set.join("/"); } else { return set.slice(0, stop).join("/"); } }); const base = getCommonPath(basePaths); if (base) { const skipIndex = countMatches(base, "/") + 1; const globPart = mini.globParts.map((s) => s.slice(skipIndex)); const resultingGlob = globPart.length === 1 ? globPart[0].join("/") : `{${globPart.map((s) => s.join("/")).join(",")}}`; return { modifiers, path: base, glob: resultingGlob }; } return { modifiers, path: "", glob: noModifierGlob }; } function createGlobString(relativeTo, glob2) { if (isAbsolute(glob2) || isGlobalGlob(glob2)) return glob2; const split = splitGlobToPathAndSpecial(glob2); const leadingPath = normalizePath(resolve(relativeTo, split.path)); if (!split.glob) { return split.modifiers + escapeGlob(leadingPath); } return `${split.modifiers}${escapeGlob(leadingPath)}/${split.glob}`; } function getCommonPath(files) { if (!files.length) { return ""; } const roots = files.map((f) => f.split("/")); if (roots.length === 1) { return roots[0].join("/"); } let i = 0; while (i < roots[0].length && new Set(roots.map((part) => part[i])).size === 1) { i++; } return roots[0].slice(0, i).join("/"); } function getCommonDirectory(files) { if (files.length === 1) { return normalizePath(dirname(files[0])); } return getCommonPath(files); } function deriveRootDir(globPaths) { const globs = new MinimatchSet(globPaths).patterns; const rootPaths = globs.flatMap( (glob2, i) => filterMap(glob2.set, (set) => { const stop = set.findIndex((part) => typeof part !== "string"); if (stop === -1) { return globPaths[i]; } else { const kept = set.slice(0, stop).join("/"); return globPaths[i].substring( 0, globPaths[i].indexOf(kept) + kept.length ); } }) ); return getCommonDirectory(rootPaths); } function nicePath(absPath) { if (!isAbsolute(absPath)) return absPath; const relativePath = relative(process.cwd(), absPath); if (relativePath.startsWith("..")) { return normalizePath(absPath); } return `./${normalizePath(relativePath)}`; } var ALREADY_NORMALIZED_WIN = /^[A-Z]:\/[^\\]*$/; function normalizePath(path) { if (process.platform === "win32") { if (ALREADY_NORMALIZED_WIN.test(path)) { return path; } path = path.replace(/\\/g, "/"); path = path.replace(/^\/([a-zA-Z])\//, (_m, m1) => `${m1}:/`); path = path.replace( /^([^:]+):\//, (_m, m1) => m1.toUpperCase() + ":/" ); } return path; } // src/lib/utils/fs.ts import { ok } from "assert"; function isFile(file) { try { return fs.statSync(file).isFile(); } catch { return false; } } function isDir(path) { try { return fs.statSync(path).isDirectory(); } catch { return false; } } function readFile(file) { const buffer = fs.readFileSync(file); switch (buffer[0]) { case 254: if (buffer[1] === 255) { let i = 0; while (i + 1 < buffer.length) { const temp = buffer[i]; buffer[i] = buffer[i + 1]; buffer[i + 1] = temp; i += 2; } return buffer.toString("ucs2", 2); } break; case 255: if (buffer[1] === 254) { return buffer.toString("ucs2", 2); } break; case 239: if (buffer[1] === 187) { return buffer.toString("utf8", 3); } } return buffer.toString("utf8", 0); } function writeFileSync2(fileName, data) { fs.mkdirSync(dirname2(normalizePath(fileName)), { recursive: true }); fs.writeFileSync(normalizePath(fileName), data); } async function writeFile(fileName, data) { await fsp.mkdir(dirname2(normalizePath(fileName)), { recursive: true }); await fsp.writeFile(normalizePath(fileName), data); } async function copy(src, dest) { const stat = await fsp.stat(src); if (stat.isDirectory()) { const contained = await fsp.readdir(src); await Promise.all( contained.map((file) => copy(join(src, file), join(dest, file))) ); } else if (stat.isFile()) { await fsp.mkdir(dirname2(dest), { recursive: true }); await fsp.copyFile(src, dest); } else { } } function copySync(src, dest) { const stat = fs.statSync(src); if (stat.isDirectory()) { const contained = fs.readdirSync(src); contained.forEach((file) => copySync(join(src, file), join(dest, file))); } else if (stat.isFile()) { fs.mkdirSync(dirname2(dest), { recursive: true }); fs.copyFileSync(src, dest); } else { } } var realpathCache = /* @__PURE__ */ new Map(); function discoverFiles(rootDir, controller) { const result = []; const dirs = [normalizePath(rootDir).split("/")]; const symlinkTargetsSeen = /* @__PURE__ */ new Set(); const { matchDirectories = false, followSymlinks = false } = controller; let dir = dirs.shift(); const handleFile = (path) => { const childPath = [...dir, path].join("/"); if (controller.matches(childPath)) { result.push(childPath); } }; const handleDirectory = (path) => { const childPath = [...dir, path]; if (controller.shouldRecurse(childPath)) { dirs.push(childPath); } }; const handleSymlink = (path) => { const childPath = [...dir, path].join("/"); let realpath; try { realpath = realpathCache.get(childPath) ?? fs.realpathSync(childPath); realpathCache.set(childPath, realpath); } catch { return; } if (symlinkTargetsSeen.has(realpath)) { return; } symlinkTargetsSeen.add(realpath); try { const stats = fs.statSync(realpath); if (stats.isDirectory()) { handleDirectory(path); } else if (stats.isFile()) { handleFile(path); } else if (stats.isSymbolicLink()) { const dirpath = dir.join("/"); if (dirpath === realpath) { return; } const targetPath = relative2(dirpath, realpath); handleSymlink(targetPath); } } catch (e) { } }; while (dir) { if (matchDirectories && controller.matches(dir.join("/"))) { result.push(dir.join("/")); } for (const child of fs.readdirSync(dir.join("/"), { withFileTypes: true })) { if (child.isFile()) { handleFile(child.name); } else if (child.isDirectory()) { handleDirectory(child.name); } else if (followSymlinks && child.isSymbolicLink()) { handleSymlink(child.name); } } dir = dirs.shift(); } return result; } function glob(pattern, root, options = {}) { const mini = new Minimatch2(pattern); const shouldIncludeNodeModules = pattern.includes("node_modules"); const controller = { matches(path) { return mini.match(path); }, shouldRecurse(childPath) { if (childPath[childPath.length - 1] === "node_modules" && !shouldIncludeNodeModules) { return false; } return mini.set.some((row) => mini.matchOne( childPath, row, /* partial */ true )); }, matchDirectories: options.includeDirectories, followSymlinks: options.followSymlinks }; return discoverFiles(root, controller); } function hasTsExtension(path) { return /\.[cm]?ts$|\.tsx$/.test(path); } function hasDeclarationFileExtension(path) { return /\.d\.[cm]?ts$/.test(path); } function discoverInParentDirExactMatch(name, dir, read, usedFile) { if (!isDir(dir)) return; const reachedTopDirectory = (dirName) => dirName === resolve2(join(dirName, "..")); while (!reachedTopDirectory(dir)) { usedFile?.(join(dir, name)); try { const content = read(readFile(join(dir, name))); if (content != null) { return { file: join(dir, name), content }; } } catch { } dir = resolve2(join(dir, "..")); } } function discoverPackageJson(dir, usedFile) { return discoverInParentDirExactMatch( "package.json", dir, (content) => { const pkg = JSON.parse(content); if (Validation.validate( { name: String, version: Validation.optional(String) }, pkg )) { return pkg; } }, usedFile ); } var packageCache = /* @__PURE__ */ new Map(); function findPackageForPath(sourcePath) { let startIndex = sourcePath.lastIndexOf("node_modules/"); if (startIndex !== -1) { startIndex += "node_modules/".length; let stopIndex = sourcePath.indexOf("/", startIndex); if (sourcePath[startIndex] === "@") { stopIndex = sourcePath.indexOf("/", stopIndex + 1); } const packageName = sourcePath.substring(startIndex, stopIndex); return [packageName, sourcePath.substring(0, stopIndex)]; } const dir = dirname2(sourcePath); const cache = packageCache.get(dir); if (cache) { return cache; } const packageJson = discoverPackageJson(dir); if (packageJson) { packageCache.set(dir, [packageJson.content.name, dirname2(packageJson.file)]); return [packageJson.content.name, dirname2(packageJson.file)]; } } function inferPackageEntryPointPaths(packagePath) { const packageDir = normalizePath(dirname2(packagePath)); const packageJson = JSON.parse(readFile(packagePath)); const exports = packageJson.exports; if (typeof exports === "string") { return resolveExport(packageDir, ".", exports, false); } if (!exports || typeof exports !== "object") { if (typeof packageJson.main === "string") { return [[".", resolve2(packageDir, packageJson.main)]]; } return []; } const results = []; if (Array.isArray(exports)) { results.push(...resolveExport(packageDir, ".", exports, true)); } else { for (const [importPath, exp] of Object.entries(exports)) { results.push(...resolveExport(packageDir, importPath, exp, false)); } } return results; } function resolveExport(packageDir, name, exportDeclaration, validatePath) { if (typeof exportDeclaration === "string") { return resolveStarredExport( packageDir, name, exportDeclaration, validatePath ); } if (Array.isArray(exportDeclaration)) { for (const item of exportDeclaration) { const result = resolveExport(packageDir, name, item, true); if (result.length) { return result; } } return []; } const EXPORT_CONDITIONS = ["typedoc", "types", "import", "node", "default"]; for (const cond in exportDeclaration) { if (EXPORT_CONDITIONS.includes(cond)) { return resolveExport( packageDir, name, exportDeclaration[cond], false ); } } return []; } function isWildcardName(name) { let starCount = 0; for (let i = 0; i < name.length; ++i) { if (name[i] === "*") { ++starCount; } } return starCount === 1; } function resolveStarredExport(packageDir, name, exportDeclaration, validatePath) { if (isWildcardName(name) && exportDeclaration.includes("*")) { let first = true; const matcher = new RegExp( "^" + escapeRegExp( normalizePath(packageDir) + "/" + exportDeclaration.replace(/^\.\//, "") ).replaceAll("\\*", () => { if (first) { first = false; return "(.*)"; } return "\\1"; }) + "$" ); const matchedFiles = discoverFiles(packageDir, { matches(path) { return matcher.test(path); }, shouldRecurse(path) { return path[path.length - 1] !== "node_modules"; } }); return matchedFiles.flatMap((path) => { const starContent = path.match(matcher); ok(starContent, "impossible, discoverFiles uses matcher"); return [[name.replace("*", starContent[1]), path]]; }); } const exportPath = resolve2(packageDir, exportDeclaration); if (validatePath && !fs.existsSync(exportPath)) { return []; } return [[name, exportPath]]; } // src/lib/utils/general.ts import { dirname as dirname3 } from "path"; import { url as debuggerUrl } from "inspector"; import { createRequire } from "module"; var req = createRequire(import.meta.url); var TYPEDOC_ROOT = dirname3(req.resolve("typedoc/package.json")); var TYPESCRIPT_ROOT = dirname3(req.resolve("typescript")); var TYPEDOC_VERSION = req("typedoc/package.json").version; var SUPPORTED_TYPESCRIPT_VERSIONS = req("typedoc/package.json").peerDependencies.typescript.split("||").map((version) => version.replace(/^\s*|\.x\s*$/g, "")); var loadSymbol = /* @__PURE__ */ Symbol.for("typedoc_loads"); var pathSymbol = /* @__PURE__ */ Symbol.for("typedoc_paths"); var g = globalThis; g[loadSymbol] = (g[loadSymbol] || 0) + 1; g[pathSymbol] ||= []; g[pathSymbol].push(import.meta.url); function hasBeenLoadedMultipleTimes() { return g[loadSymbol] !== 1; } function getLoadedPaths() { return g[pathSymbol] || []; } function isDebugging() { return !!debuggerUrl(); } // src/lib/utils/loggers.ts import ts from "typescript"; import { resolve as resolve3 } from "path"; import { ConsoleLogger, LogLevel } from "#utils"; var Colors = { red: "\x1B[91m", yellow: "\x1B[93m", cyan: "\x1B[96m", gray: "\x1B[90m", black: "\x1B[47m\x1B[30m", reset: "\x1B[0m" }; function color(text, color2) { if ("NO_COLOR" in process.env) return text; return `${Colors[color2]}${text}${Colors.reset}`; } var messagePrefixes = { [LogLevel.Error]: color("[error]", "red"), [LogLevel.Warn]: color("[warning]", "yellow"), [LogLevel.Info]: color("[info]", "cyan"), [LogLevel.Verbose]: color("[debug]", "gray") }; function diagnostics(logger, diagnostics2) { for (const d of diagnostics2) { diagnostic(logger, d); } } function diagnostic(logger, diagnostic2) { const output = ts.formatDiagnosticsWithColorAndContext([diagnostic2], { getCanonicalFileName: resolve3, getCurrentDirectory: () => process.cwd(), getNewLine: () => ts.sys.newLine }); switch (diagnostic2.category) { case ts.DiagnosticCategory.Error: logger.log(output, LogLevel.Error); break; case ts.DiagnosticCategory.Warning: logger.log(output, LogLevel.Warn); break; case ts.DiagnosticCategory.Message: logger.log(output, LogLevel.Info); break; } } var FancyConsoleLogger = class extends ConsoleLogger { addContext(message, level, ...args) { if (typeof args[0] === "undefined") { return `${messagePrefixes[level]} ${message}`; } if (typeof args[0] !== "number") { const node = args[0]; return this.addContext( message, level, node.getStart(node.getSourceFile(), false), args[0].getSourceFile() ); } const [pos, file] = args; const path = nicePath(file.fileName); const { line, character } = file.getLineAndCharacterOfPosition(pos); const location = `${color(path, "cyan")}:${color( `${line + 1}`, "yellow" )}:${color(`${character}`, "yellow")}`; const start = file.text.lastIndexOf("\n", pos) + 1; let end = file.text.indexOf("\n", start); if (end === -1) end = file.text.length; const prefix = `${location} - ${messagePrefixes[level]}`; const context = `${color( `${line + 1}`, "black" )} ${file.text.substring(start, end)}`; return `${prefix} ${message} ${context} `; } }; // src/lib/utils/plugins.ts import { isAbsolute as isAbsolute2 } from "path"; import { pathToFileURL } from "url"; import { i18n } from "#utils"; async function loadPlugins(app, plugins) { for (const plugin of plugins) { const pluginDisplay = getPluginDisplayName(plugin); try { let initFunction; if (typeof plugin === "function") { initFunction = plugin; } else { let instance; try { const esmPath = isAbsolute2(plugin) ? pathToFileURL(plugin).toString() : plugin; instance = await import(esmPath); } catch (error) { if (error.code === "ERR_UNSUPPORTED_DIR_IMPORT") { instance = __require(plugin); } else { throw error; } } initFunction = instance.load; } if (typeof initFunction === "function") { await initFunction(app); app.logger.info(i18n.loaded_plugin_0(pluginDisplay)); } else { app.logger.error( i18n.invalid_plugin_0_missing_load_function( pluginDisplay ) ); } } catch (error) { app.logger.error( i18n.plugin_0_could_not_be_loaded(pluginDisplay) ); if (error instanceof Error && error.stack) { app.logger.error(error.stack); } } } } function getPluginDisplayName(plugin) { if (typeof plugin === "function") { return plugin.name || "function"; } const path = nicePath(plugin); if (path.startsWith("./node_modules/")) { return path.substring("./node_modules/".length); } return plugin; } // src/lib/utils/options/defaults.ts var defaults_exports = {}; __export(defaults_exports, { blockTags: () => blockTags2, cascadedModifierTags: () => cascadedModifierTags, excludeNotDocumentedKinds: () => excludeNotDocumentedKinds, excludeTags: () => excludeTags, highlightLanguages: () => highlightLanguages, ignoredHighlightLanguages: () => ignoredHighlightLanguages, inlineTags: () => inlineTags2, kindSortOrder: () => kindSortOrder, modifierTags: () => modifierTags2, notRenderedTags: () => notRenderedTags, preservedTypeAnnotationTags: () => preservedTypeAnnotationTags, requiredToBeDocumented: () => requiredToBeDocumented, sort: () => sort }); // src/lib/utils/options/tsdoc-defaults.ts var tsdoc_defaults_exports = {}; __export(tsdoc_defaults_exports, { blockTags: () => blockTags, inlineTags: () => inlineTags, modifierTags: () => modifierTags, tsdocBlockTags: () => tsdocBlockTags, tsdocInlineTags: () => tsdocInlineTags, tsdocModifierTags: () => tsdocModifierTags }); var tsdocBlockTags = [ "@defaultValue", "@deprecated", "@example", "@jsx", "@param", "@privateRemarks", "@remarks", "@returns", "@see", "@throws", "@typeParam" ]; var blockTags = [ ...tsdocBlockTags, "@author", "@callback", "@category", "@categoryDescription", "@default", "@document", "@extends", "@augments", // Alias for @extends "@yields", "@group", "@groupDescription", "@import", "@inheritDoc", "@license", "@module", "@mergeModuleWith", "@prop", "@property", "@return", "@satisfies", "@since", "@sortStrategy", "@template", // Alias for @typeParam "@this", "@type", "@typedef", "@summary", "@preventInline", "@inlineType", "@preventExpand", "@expandType" ]; var tsdocInlineTags = ["@link", "@inheritDoc", "@label"]; var inlineTags = [ ...tsdocInlineTags, "@linkcode", "@linkplain", "@include", "@includeCode" ]; var tsdocModifierTags = [ "@alpha", "@beta", "@eventProperty", "@experimental", "@internal", "@override", "@packageDocumentation", "@public", "@readonly", "@sealed", "@virtual" ]; var modifierTags = [ ...tsdocModifierTags, "@abstract", "@class", "@disableGroups", "@enum", "@event", "@expand", "@hidden", "@hideCategories", "@hideconstructor", "@hideGroups", "@ignore", "@inline", "@interface", "@namespace", "@function", "@overload", "@private", "@protected", "@reexport", "@showCategories", "@showGroups", "@useDeclaredType", "@primaryExport" ]; // src/lib/utils/options/defaults.ts var excludeNotDocumentedKinds = [ "Module", "Namespace", "Enum", // Not including enum member here by default "Variable", "Function", "Class", "Interface", "Constructor", "Property", "Method", "CallSignature", "IndexSignature", "ConstructorSignature", "Accessor", "GetSignature", "SetSignature", "TypeAlias", "Reference" ]; var excludeTags = [ "@override", "@virtual", "@privateRemarks", "@satisfies", "@overload", "@inline", "@inlineType" ]; var blockTags2 = blockTags; var inlineTags2 = inlineTags; var modifierTags2 = modifierTags; var cascadedModifierTags = [ "@alpha", "@beta", "@experimental" ]; var preservedTypeAnnotationTags = []; var notRenderedTags = [ "@showCategories", "@showGroups", "@hideCategories", "@hideGroups", "@disableGroups", "@expand", "@preventExpand", "@expandType", "@summary", "@group", "@groupDescription", "@category", "@categoryDescription" ]; var highlightLanguages = [ "bash", "console", "css", "html", "javascript", "json", "jsonc", "json5", "yaml", "tsx", "typescript" ]; var ignoredHighlightLanguages = []; var sort = [ "kind", "instance-first", "alphabetical-ignoring-documents" ]; var kindSortOrder = [ "Document", "Project", "Module", "Namespace", "Enum", "EnumMember", "Class", "Interface", "TypeAlias", "Constructor", "Property", "Variable", "Function", "Accessor", "Method", "Reference" ]; var requiredToBeDocumented = [ "Enum", "EnumMember", "Variable", "Function", "Class", "Interface", "Property", "Method", "Accessor", "TypeAlias" ]; // src/lib/utils/sort.ts import { ReflectionKind } from "#models"; var SORT_STRATEGIES = [ "source-order", "alphabetical", "alphabetical-ignoring-documents", "enum-value-ascending", "enum-value-descending", "enum-member-source-order", "static-first", "instance-first", "visibility", "required-first", "kind", "external-last", "documents-first", "documents-last" ]; var sorts = { "source-order"(a, b) { const aSymbol = a.project.getSymbolIdFromReflection(a); const bSymbol = b.project.getSymbolIdFromReflection(b); if (aSymbol && bSymbol) { if (aSymbol.packageName < bSymbol.packageName) { return true; } if (aSymbol.packageName === bSymbol.packageName && aSymbol.packagePath < bSymbol.packagePath) { return true; } if (aSymbol.packageName === bSymbol.packageName && aSymbol.packagePath === bSymbol.packagePath && aSymbol.pos < bSymbol.pos) { return true; } return false; } return false; }, alphabetical(a, b) { return a.name.localeCompare(b.name) < 0; }, "alphabetical-ignoring-documents"(a, b) { if (a.kindOf(ReflectionKind.Document) || b.kindOf(ReflectionKind.Document)) { return false; } return a.name.localeCompare(b.name) < 0; }, "enum-value-ascending"(a, b) { if (a.kind == ReflectionKind.EnumMember && b.kind == ReflectionKind.EnumMember) { const aRefl = a; const bRefl = b; const aValue = aRefl.type?.type === "literal" ? aRefl.type.value : -Infinity; const bValue = bRefl.type?.type === "literal" ? bRefl.type.value : -Infinity; return aValue < bValue; } return false; }, "enum-value-descending"(a, b) { if (a.kind == ReflectionKind.EnumMember && b.kind == ReflectionKind.EnumMember) { const aRefl = a; const bRefl = b; const aValue = aRefl.type?.type === "literal" ? aRefl.type.value : -Infinity; const bValue = bRefl.type?.type === "literal" ? bRefl.type.value : -Infinity; return bValue < aValue; } return false; }, "enum-member-source-order"(a, b, data) { if (a.kind === ReflectionKind.EnumMember && b.kind === ReflectionKind.EnumMember) { return sorts["source-order"](a, b, data); } return false; }, "static-first"(a, b) { return a.flags.isStatic && !b.flags.isStatic; }, "instance-first"(a, b) { return !a.flags.isStatic && b.flags.isStatic; }, visibility(a, b) { if (a.flags.isPrivate) { return false; } if (a.flags.isProtected) { return b.flags.isPrivate; } if (b.flags.isPrivate || b.flags.isProtected) { return true; } return false; }, "required-first"(a, b) { return !a.flags.isOptional && b.flags.isOptional; }, kind(a, b, { kindSortOrder: kindSortOrder2 }) { return kindSortOrder2.indexOf(a.kind) < kindSortOrder2.indexOf(b.kind); }, "external-last"(a, b) { return !a.flags.isExternal && b.flags.isExternal; }, "documents-first"(a, b) { return a.kindOf(ReflectionKind.Document) && !b.kindOf(ReflectionKind.Document); }, "documents-last"(a, b) { return !a.kindOf(ReflectionKind.Document) && b.kindOf(ReflectionKind.Document); } }; function isValidSortStrategy(strategy) { return SORT_STRATEGIES.includes(strategy); } function getSortFunction(opts, strategies = opts.getValue("sort")) { const kindSortOrder2 = opts.getValue("kindSortOrder").map((k) => ReflectionKind[k]); for (const kind of kindSortOrder) { if (!kindSortOrder2.includes(ReflectionKind[kind])) { kindSortOrder2.push(ReflectionKind[kind]); } } const data = { kindSortOrder: kindSortOrder2 }; return function sortReflections(reflections) { reflections.sort((a, b) => { for (const s of strategies) { if (sorts[s](a, b, data)) { return -1; } if (sorts[s](b, a, data)) { return 1; } } return 0; }); }; } // src/lib/utils/options/index.ts var options_exports = {}; __export(options_exports, { ArgumentsReader: () => ArgumentsReader, CommentStyle: () => CommentStyle, EmitStrategy: () => EmitStrategy, Option: () => Option, OptionDefaults: () => defaults_exports, Options: () => Options, PackageJsonReader: () => PackageJsonReader, ParameterHint: () => ParameterHint, ParameterType: () => ParameterType, TSConfigReader: () => TSConfigReader, TSDocDefaults: () => tsdoc_defaults_exports, TypeDocReader: () => TypeDocReader, rootPackageOptions: () => rootPackageOptions }); // src/lib/utils/options/declaration.ts import { isAbsolute as isAbsolute3, join as join2, resolve as resolve4 } from "path"; import { i18n as i18n2 } from "#utils"; var EmitStrategy = { both: "both", // Emit both documentation and JS docs: "docs", // Emit documentation, but not JS (default) none: "none" // Emit nothing, just convert and run validation }; var CommentStyle = { JSDoc: "jsdoc", Block: "block", Line: "line", TripleSlash: "triple-slash", All: "all" }; var rootPackageOptions = [ // Configuration Options "plugin", // Input Options "packageOptions", // Output Options "outputs", "out", "html", "json", "pretty", "theme", "router", "lightHighlightTheme", "darkHighlightTheme", "highlightLanguages", "ignoredHighlightLanguages", "typePrintWidth", "customCss", "customJs", "customFooterHtml", "customFooterHtmlDisableWrapper", "markdownItOptions", "markdownItLoader", "cname", "favicon", "sourceLinkExternal", "markdownLinkExternal", "lang", "locales", "githubPages", "cacheBust", "hideGenerator", "searchInComments", "searchInDocuments", "cleanOutputDir", "titleLink", "navigationLinks", "sidebarLinks", "navigation", "headings", "sluggerConfiguration", "navigationLeaves", "visibilityFilters", "searchCategoryBoosts", "searchGroupBoosts", "hostedBaseUrl", "useHostedBaseUrlForAbsoluteLinks", "useFirstParagraphOfCommentAsSummary", "includeHierarchySummary", // Comment Options "notRenderedTags", // Organization Options // Validation Options "treatWarningsAsErrors", "treatValidationWarningsAsErrors", // Other Options "watch", "preserveWatchOutput", "help", "version", "showConfig", "logLevel" ]; var ParameterHint = /* @__PURE__ */ ((ParameterHint2) => { ParameterHint2[ParameterHint2["File"] = 0] = "File"; ParameterHint2[ParameterHint2["Directory"] = 1] = "Directory"; return ParameterHint2; })(ParameterHint || {}); var ParameterType = /* @__PURE__ */ ((ParameterType2) => { ParameterType2[ParameterType2["String"] = 0] = "String"; ParameterType2[ParameterType2["Path"] = 1] = "Path"; ParameterType2[ParameterType2["UrlOrPath"] = 2] = "UrlOrPath"; ParameterType2[ParameterType2["Number"] = 3] = "Number"; ParameterType2[ParameterType2["Boolean"] = 4] = "Boolean"; ParameterType2[ParameterType2["Map"] = 5] = "Map"; ParameterType2[ParameterType2["Mixed"] = 6] = "Mixed"; ParameterType2[ParameterType2["Array"] = 7] = "Array"; ParameterType2[ParameterType2["PathArray"] = 8] = "PathArray"; ParameterType2[ParameterType2["ModuleArray"] = 9] = "ModuleArray"; ParameterType2[ParameterType2["PluginArray"] = 10] = "PluginArray"; ParameterType2[ParameterType2["GlobArray"] = 11] = "GlobArray"; ParameterType2[ParameterType2["Object"] = 12] = "Object"; ParameterType2[ParameterType2["Flags"] = 13] = "Flags"; return ParameterType2; })(ParameterType || {}); function toStringArray(value, option) { if (Array.isArray(value) && value.every((v) => typeof v === "string")) { return value; } else if (typeof value === "string") { return [value]; } throw new Error(i18n2.option_0_must_be_an_array_of_string(option.name)); } function toStringOrFunctionArray(value, option) { if (Array.isArray(value) && value.every((v) => typeof v === "string" || typeof v === "function")) { return value; } else if (typeof value === "string") { return [value]; } throw new Error(i18n2.option_0_must_be_an_array_of_string_or_functions(option.name)); } var converters = { [0 /* String */](value, option) { const stringValue = value == null ? "" : String(value); option.validate?.(stringValue); return stringValue; }, [1 /* Path */](value, option, configPath) { const stringValue = ( // eslint-disable-next-line @typescript-eslint/no-base-to-string value == null ? "" : resolve4(configPath, String(value)) ); option.validate?.(stringValue); return normalizePath(stringValue); }, [2 /* UrlOrPath */](value, option, configPath) { const stringValue = value == null ? "" : String(value); if (/^https?:\/\//i.test(stringValue)) { option.validate?.(stringValue); return stringValue; } const resolved = normalizePath(resolve4(configPath, stringValue)); option.validate?.(resolved); return resolved; }, [3 /* Number */](value, option) { const numValue = parseInt(String(value), 10) || 0; if (!valueIsWithinBounds(numValue, option.minValue, option.maxValue)) { throw new Error( getBoundsError( option.name, option.minValue, option.maxValue ) ); } option.validate?.(numValue); return numValue; }, [4 /* Boolean */](value) { return !!value; }, [7 /* Array */](value, option) { const strArrValue = toStringArray(value, option); option.validate?.(strArrValue); return strArrValue; }, [8 /* PathArray */](value, option, configPath) { const strArrValue = toStringArray(value, option); const normalized = strArrValue.map((path) => normalizePath(resolve4(configPath, path))); option.validate?.(normalized); return normalized; }, // eslint-disable-next-line @typescript-eslint/no-deprecated [9 /* ModuleArray */](value, option, configPath) { const strArrValue = toStringArray(value, option); const resolved = resolveModulePaths(strArrValue, configPath); option.validate?.(resolved); return resolved; }, [10 /* PluginArray */](value, option, configPath) { const arrayValue = toStringOrFunctionArray(value, option); const resolved = arrayValue.map( (plugin) => typeof plugin === "function" ? plugin : resolveModulePath(plugin, configPath) ); return resolved; }, [11 /* GlobArray */](value, option, configPath) { const toGlobString = (v) => { const s = String(v); if (/\\[^?*()[\]\\{}]/.test(s)) { throw new Error(i18n2.glob_0_should_use_posix_slash(s)); } return createGlobString(configPath, s); }; const strArrValue = toStringArray(value, option); const globs = strArrValue.map(toGlobString); option.validate?.(globs); return globs; }, [5 /* Map */](value, option) { const key = String(value); if (option.map instanceof Map) { if (option.map.has(key)) { return option.map.get(key); } else if ([...option.map.values()].includes(value)) { return value; } } else if (key in option.map) { if (isTsNumericEnum(option.map) && typeof value === "number") { return value; } return option.map[key]; } else if (Object.values(option.map).includes(value)) { return value; } throw new Error(getMapError(option.map, option.name)); }, [6 /* Mixed */](value, option) { option.validate?.(value); return value; }, [12 /* Object */](value, option, _configPath, oldValue) { option.validate?.(value); if (typeof oldValue !== "undefined") { value = { ...oldValue, ...value }; } return value; }, [13 /* Flags */](value, option) { if (typeof value === "boolean") { value = Object.fromEntries( Object.keys(option.defaults).map((key) => [key, value]) ); } if (typeof value !== "object" || value == null) { throw new Error( i18n2.expected_object_with_flag_values_for_0(option.name) ); } const obj = { ...value }; for (const key of Object.keys(obj)) { if (!Object.prototype.hasOwnProperty.call(option.defaults, key)) { throw new Error( i18n2.flag_0_is_not_valid_for_1_expected_2( key, option.name, Object.keys(option.defaults).join(", ") ) ); } if (typeof obj[key] !== "boolean") { if (obj[key] == null) { obj[key] = option.defaults[key]; } else { throw new Error( i18n2.flag_values_for_0_must_be_booleans(option.name) ); } } } return obj; } }; function convert(value, option, configPath, oldValue) { const _converters = converters; return _converters[option.type ?? 0 /* String */]( value, option, configPath, oldValue ); } var defaultGetters = { [0 /* String */](option) { return option.defaultValue ?? ""; }, [1 /* Path */](option) { const defaultStr = option.defaultValue ?? ""; if (defaultStr == "") { return ""; } return normalizePath( isAbsolute3(defaultStr) ? defaultStr : join2(process.cwd(), defaultStr) ); }, [2 /* UrlOrPath */](option) { const defaultStr = option.defaultValue ?? ""; if (defaultStr == "") { return ""; } if (/^https?:\/\//i.test(defaultStr)) { return defaultStr; } return isAbsolute3(defaultStr) ? defaultStr : join2(process.cwd(), defaultStr); }, [3 /* Number */](option) { return option.defaultValue ?? 0; }, [4 /* Boolean */](option) { return option.defaultValue ?? false; }, [5 /* Map */](option) { return option.defaultValue; }, [6 /* Mixed */](option) { return option.defaultValue; }, [12 /* Object */](option) { return option.defaultValue; }, [7 /* Array */](option) { return option.defaultValue?.slice() ?? []; }, [8 /* PathArray */](option) { return option.defaultValue?.map((value) => normalizePath(resolve4(process.cwd(), value))) ?? []; }, // eslint-disable-next-line @typescript-eslint/no-deprecated [9 /* ModuleArray */](option) { if (option.defaultValue) { return resolveModulePaths(option.defaultValue, process.cwd()); } return []; }, [10 /* PluginArray */](option) { if (option.defaultValue) { return resolveModulePaths(option.defaultValue, process.cwd()); } return []; }, [11 /* GlobArray */](option) { return (option.defaultValue ?? []).map((g2) => createGlobString(normalizePath(process.cwd()), g2)); }, [13 /* Flags */](option) { return { ...option.defaults }; } }; function getDefaultValue(option) { const getters = defaultGetters; return getters[option.type ?? 0 /* String */](option); } function resolveModulePaths(modules, configPath) { return modules.map((path) => resolveModulePath(path, configPath)); } function resolveModulePath(path, configPath) { if (path.startsWith(".")) { return normalizePath(resolve4(configPath, path)); } return normalizePath(path); } function isTsNumericEnum(map) { return Object.values(map).every((key) => map[map[key]] === key); } function getMapError(map, name) { let keys = map instanceof Map ? [...map.keys()] : Object.keys(map); if (!(map instanceof Map) && isTsNumericEnum(map)) { keys = keys.filter((key) => Number.isNaN(parseInt(key, 10))); } return i18n2.option_0_must_be_one_of_1(name, keys.join(", ")); } function getBoundsError(name, minValue, maxValue) { if (isFiniteNumber(minValue) && isFiniteNumber(maxValue)) { return i18n2.option_0_must_be_between_1_and_2( name, String(minValue), String(maxValue) ); } else if (isFiniteNumber(minValue)) { return i18n2.option_0_must_be_equal_to_or_greater_than_1( name, String(minValue) ); } else { return i18n2.option_0_must_be_less_than_or_equal_to_1( name, String(maxValue) ); } } function isFiniteNumber(value) { return Number.isFinite(value); } function valueIsWithinBounds(value, minValue, maxValue) { if (isFiniteNumber(minValue) && isFiniteNumber(maxValue)) { return minValue <= value && value <= maxValue; } else if (isFiniteNumber(minValue)) { return minValue <= value; } else if (isFiniteNumber(maxValue)) { return value <= maxValue; } else { return true; } } // src/lib/utils/options/options.ts import ts3 from "typescript"; import { resolve as resolve7 } from "path"; // src/lib/utils/entry-point.ts import { assertNever, i18n as i18n4 } from "#utils"; import * as FS from "fs"; import { join as join4, relative as relative4, resolve as resolve6 } from "path"; import ts2 from "typescript"; // src/lib/utils/declaration-maps.ts import { existsSync as existsSync2 } from "fs"; import { Validation as Validation2 } from "#utils"; import { join as join3, relative as relative3, resolve as resolve5 } from "path"; var declarationMapCache = /* @__PURE__ */ new Map(); function resolveDeclarationMaps(file) { if (!/\.d\.[cm]?ts$/.test(file)) return file; if (declarationMapCache.has(file)) return declarationMapCache.get(file); const mapFile = file + ".map"; if (!existsSync2(mapFile)) return file; let sourceMap; try { sourceMap = JSON.parse(readFile(mapFile)); } catch { return file; } if (Validation2.validate( { file: String, sourceRoot: Validation2.optional(String), sources: [Array, String] }, sourceMap )) { let source = sourceMap.sources[0]; if (sourceMap.sourceRoot !== void 0) { source = source.replace(/^\//, ""); source = join3(sourceMap.sourceRoot, source); } const result = resolve5(mapFile, "..", source); declarationMapCache.set(file, result); return result; } return file; } function addInferredDeclarationMapPaths(opts, files) { const rootDir = opts.rootDir || getCommonDirectory(files); const declDir = opts.declarationDir || opts.outDir || rootDir; for (const file of files) { const mapFile = normalizePath( resolve5(declDir, relative3(rootDir, file)).replace( /\.([cm]?[tj]s)x?$/, ".d.$1" ) ); declarationMapCache.set(mapFile, file); } } // src/lib/utils/package-manifest.ts import { dirname as dirname4 } from "path"; import { i18n as i18n3 } from "#utils"; function hasOwnProperty(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); } function loadPackageManifest(logger, packageJsonPath) { const packageJson = JSON.parse(readFile(packageJsonPath)); if (typeof packageJson !== "object" || !packageJson) { logger.error( i18n3.file_0_not_an_object(nicePath(packageJsonPath)) ); return void 0; } return packageJson; } function getPackagePaths(packageJSON) { if (Array.isArray(packageJSON["workspaces"]) && packageJSON["workspaces"].every((i) => typeof i === "string")) { return packageJSON["workspaces"]; } if (typeof packageJSON["workspaces"] === "object" && packageJSON["workspaces"] != null) { const workspaces = packageJSON["workspaces"]; if (hasOwnProperty(workspaces, "packages") && Array.isArray(workspaces["packages"]) && workspaces["packages"].every((i) => typeof i === "string")) { return workspaces["packages"]; } } return void 0; } function expandPackages(logger, packageJsonDir, workspaces, exclude) { return workspaces.flatMap((workspace) => { const expandedPackageJsonPaths = glob( createGlobString(packageJsonDir, `${workspace}/package.json`), packageJsonDir ); if (expandedPackageJsonPaths.length === 0) { logger.warn( i18n3.entry_point_0_did_not_match_any_packages( nicePath(workspace) ) ); } else if (expandedPackageJsonPaths.length !== 1) { logger.verbose( `Expanded ${nicePath(workspace)} to: ${expandedPackageJsonPaths.map(nicePath).join("\n ")}` ); } return expandedPackageJsonPaths.flatMap((packageJsonPath) => { if (exclude.matchesAny(dirname4(packageJsonPath))) { return []; } const packageJson = loadPackageManifest(logger, packageJsonPath); if (packageJson === void 0) { return []; } const packagePaths = getPackagePaths(packageJson); if (packagePaths === void 0) { return [dirname4(packageJsonPath)]; } return expandPackages( logger, normalizePath(dirname4(packageJsonPath)), packagePaths.map((p) => createGlobString(normalizePath(dirname4(packageJsonPath)), p)), exclude ); }); }); } // src/lib/utils/entry-point.ts var EntryPointStrategy = { /** * The default behavior in v0.22+, expects all provided entry points as being part of a single program. * Any directories included in the entry point list will result in `dir/index.([cm][tj]s|[tj]sx?)` being used. */ Resolve: "resolve", /** * The default behavior in v0.21 and earlier. Behaves like the resolve behavior, but will recursively * expand directories into an entry point for each file within the directory. */ Expand: "expand", /** * Run TypeDoc in each directory passed as an entry point. Once all directories have been converted, * use the merge option to produce final output. */ Packages: "packages", /** * Merges multiple previously generated output from TypeDoc's --json output together into a single project. */ Merge: "merge" }; function inferEntryPoints(logger, options, programs) { const packageJson = discoverPackageJson( options.packageDir ?? process.cwd() ); if (!packageJson) { logger.warn(i18n4.no_entry_points_provided()); return []; } const pathEntries = inferPackageEntryPointPaths(packageJson.file); const entryPoints = []; programs ||= getEntryPrograms( pathEntries.map((p) => p[1]), logger, options ); const jsToTsSource = /* @__PURE__ */ new Map(); for (const program of programs) { const opts = program.getCompilerOptions(); const rootDir = opts.rootDir || getCommonDirectory(program.getRootFileNames()); const outDir = opts.outDir || rootDir; for (const tsFile of program.getRootFileNames()) { const jsFile = normalizePath( resolve6(outDir, relative4(rootDir, tsFile)).replace( /\.([cm]?)[tj]sx?$/, ".$1js" ) ); jsToTsSource.set(jsFile, tsFile); } } for (const [name, path] of pathEntries) { const displayName = name.replace(/^\.\/?/, ""); const targetPath = jsToTsSource.get(normalizePath(path)) || resolveDeclarationMaps(path) || path; const program = programs.find((p) => p.getSourceFile(targetPath)); if (program) { entryPoints.push({ displayName, program, sourceFile: program.getSourceFile(targetPath) }); } else if (/\.[cm]?js$/.test(path)) { logger.warn( i18n4.failed_to_resolve_0_to_ts_path(nicePath(path)) ); } } if (entryPoints.length === 0) { logger.warn(i18n4.no_entry_points_provided()); return []; } logger.verbose( `Inferred entry points to be: ${entryPoints.map((e) => nicePath(e.sourceFile.fileName)).join("\n ")}` ); return entryPoints; } function getEntryPoints(logger, options) { if (!options.isSet("entryPoints")) { logger.warn(i18n4.no_entry_points_provided()); return []; } const entryPoints = options.getValue("entryPoints"); const exclude = options.getValue("exclude"); if (entryPoints.length === 0) { return []; } let result; const strategy = options.getValue("entryPointStrategy"); switch (strategy) { case EntryPointStrategy.Resolve: result = getEntryPointsForPaths( logger, expandGlobs(entryPoints, exclude, logger), options ); break; case EntryPointStrategy.Expand: result = getExpandedEntryPointsForPaths( logger, expandGlobs(entryPoints, exclude, logger), options ); break; case EntryPointStrategy.Merge: case EntryPointStrategy.Packages: return []; default: assertNever(strategy); } if (result.length === 0) { logger.error(i18n4.unable_to_find_any_entry_points()); return; } return result; } function getDocumentEntryPoints(logger, options) { const docGlobs = options.getValue("projectDocuments"); if (docGlobs.length === 0) { return []; } const docPaths = expandGlobs(docGlobs, [], logger); const supportedFileRegex = /\.(md|markdown)$/; const expanded = expandInputFiles( logger, docPaths, options, supportedFileRegex ); const baseDir = options.getValue("displayBasePath") || options.getValue("basePath") || getCommonDirectory(expanded); return expanded.map((path) => { return { displayName: relative4(baseDir, path).replace(/\.[^.]+$/, ""), path }; }); } function getWatchEntryPoints(logger, options, program) { let result; const entryPoints = options.getValue("entryPoints"); const exclude = options.getValue("exclude"); const strategy = options.getValue("entryPointStrategy"); switch (strategy) { case EntryPointStrategy.Resolve: if (options.isSet("entryPoints")) { result = getEntryPointsForPaths( logger, expandGlobs(entryPoints, exclude, logger), options, [program] ); } else { result = inferEntryPoints(logger, options, [program]); } break; case EntryPointStrategy.Expand: if (options.isSet("entryPoints")) { result = getExpandedEntryPointsForPaths( logger, expandGlobs(entryPoints, exclude, logger), options, [program] ); } else { result = inferEntryPoints(logger, options, [program]); } break; case EntryPointStrategy.Packages: logger.error(i18n4.watch_does_not_support_packages_mode()); break; case EntryPointStrategy.Merge: logger.error(i18n4.watch_does_not_support_merge_mode()); break; default: assertNever(strategy); } if (result && result.length === 0) { logger.error(i18n4.unable_to_find_any_entry_points()); return; } return result; } function getPackageDir