Comparing version 0.23.15 to 0.23.16
@@ -134,3 +134,3 @@ "use strict"; | ||
// Try to create a new repository | ||
const repository = repository_1.Repository.tryCreateRepository(dirName, this.gitRevision, this.gitRemote); | ||
const repository = repository_1.Repository.tryCreateRepository(dirName, this.gitRevision, this.gitRemote, this.application.logger); | ||
if (repository) { | ||
@@ -137,0 +137,0 @@ this.repositories[repository.path.toLowerCase()] = repository; |
@@ -515,5 +515,8 @@ "use strict"; | ||
assert(parentSymbol, `No parent symbol found for ${symbol.name} in ${context.scope.name}`); | ||
return (parentSymbol | ||
.getDeclarations() | ||
?.some((d) => symbol.getDeclarations()?.some((d2) => d2.parent === d)) === false); | ||
const parents = parentSymbol.declarations?.slice() || []; | ||
const constructorDecls = parents.flatMap((parent) => ts.isClassDeclaration(parent) | ||
? parent.members.filter(ts.isConstructorDeclaration) | ||
: []); | ||
parents.push(...constructorDecls); | ||
return (parents.some((d) => symbol.getDeclarations()?.some((d2) => d2.parent === d)) === false); | ||
} | ||
@@ -520,0 +523,0 @@ function setModifiers(symbol, declaration, reflection) { |
@@ -1,2 +0,2 @@ | ||
import { RepositoryType } from "../../models"; | ||
import type { Logger } from "../../utils"; | ||
export declare const gitIsInstalled: boolean; | ||
@@ -8,36 +8,18 @@ /** | ||
/** | ||
* The root path of this repository. | ||
* The path of this repository on disk. | ||
*/ | ||
path: string; | ||
/** | ||
* The name of the branch this repository is on right now. | ||
* All files tracked by the repository. | ||
*/ | ||
branch: string; | ||
files: Set<string>; | ||
/** | ||
* A list of all files tracked by the repository. | ||
* The base url for link creation. | ||
*/ | ||
files: string[]; | ||
baseUrl: string; | ||
/** | ||
* The user/organization name of this repository on GitHub. | ||
* The anchor prefix used to select lines, usually `L` | ||
*/ | ||
user?: string; | ||
anchorPrefix: string; | ||
/** | ||
* The project name of this repository on GitHub. | ||
*/ | ||
project?: string; | ||
/** | ||
* The hostname for this GitHub/Bitbucket/.etc project. | ||
* | ||
* Defaults to: `github.com` (for normal, public GitHub instance projects) | ||
* | ||
* Can be the hostname for an enterprise version of GitHub, e.g. `github.acme.com` | ||
* (if found as a match in the list of git remotes). | ||
*/ | ||
hostname: string; | ||
/** | ||
* Whether this is a GitHub, Bitbucket, or other type of repository. | ||
*/ | ||
type: RepositoryType; | ||
private urlCache; | ||
/** | ||
* Create a new Repository instance. | ||
@@ -47,11 +29,4 @@ * | ||
*/ | ||
constructor(path: string, gitRevision: string, repoLinks: string[]); | ||
constructor(path: string, baseUrl: string); | ||
/** | ||
* Check whether the given file is tracked by this repository. | ||
* | ||
* @param fileName The name of the file to test for. | ||
* @returns TRUE when the file is part of the repository, otherwise FALSE. | ||
*/ | ||
contains(fileName: string): boolean; | ||
/** | ||
* Get the URL of the given file on GitHub or Bitbucket. | ||
@@ -73,3 +48,4 @@ * | ||
*/ | ||
static tryCreateRepository(path: string, gitRevision: string, gitRemote: string): Repository | undefined; | ||
static tryCreateRepository(path: string, gitRevision: string, gitRemote: string, logger: Logger): Repository | undefined; | ||
} | ||
export declare function guessBaseUrl(gitRevision: string, remotes: string[]): string | undefined; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.Repository = exports.gitIsInstalled = void 0; | ||
exports.guessBaseUrl = exports.Repository = exports.gitIsInstalled = void 0; | ||
const child_process_1 = require("child_process"); | ||
const models_1 = require("../../models"); | ||
const base_path_1 = require("../utils/base-path"); | ||
@@ -25,87 +24,20 @@ const TEN_MEGABYTES = 1024 * 10000; | ||
*/ | ||
constructor(path, gitRevision, repoLinks) { | ||
constructor(path, baseUrl) { | ||
/** | ||
* A list of all files tracked by the repository. | ||
* All files tracked by the repository. | ||
*/ | ||
this.files = []; | ||
/** | ||
* The hostname for this GitHub/Bitbucket/.etc project. | ||
* | ||
* Defaults to: `github.com` (for normal, public GitHub instance projects) | ||
* | ||
* Can be the hostname for an enterprise version of GitHub, e.g. `github.acme.com` | ||
* (if found as a match in the list of git remotes). | ||
*/ | ||
this.hostname = "github.com"; | ||
/** | ||
* Whether this is a GitHub, Bitbucket, or other type of repository. | ||
*/ | ||
this.type = models_1.RepositoryType.GitHub; | ||
this.urlCache = new Map(); | ||
this.files = new Set(); | ||
this.path = path; | ||
this.branch = gitRevision || "master"; | ||
for (let i = 0, c = repoLinks.length; i < c; i++) { | ||
let match = /(github(?!.us)(?:\.[a-z]+)*\.[a-z]{2,})[:/]([^/]+)\/(.*)/.exec(repoLinks[i]); | ||
// Github Enterprise | ||
if (!match) { | ||
match = /(\w+\.githubprivate.com)[:/]([^/]+)\/(.*)/.exec(repoLinks[i]); | ||
} | ||
// Github Enterprise | ||
if (!match) { | ||
match = /(\w+\.ghe.com)[:/]([^/]+)\/(.*)/.exec(repoLinks[i]); | ||
} | ||
// Github Enterprise | ||
if (!match) { | ||
match = /(\w+\.github.us)[:/]([^/]+)\/(.*)/.exec(repoLinks[i]); | ||
} | ||
if (!match) { | ||
match = /(bitbucket.org)[:/]([^/]+)\/(.*)/.exec(repoLinks[i]); | ||
} | ||
if (!match) { | ||
match = /(gitlab.com)[:/]([^/]+)\/(.*)/.exec(repoLinks[i]); | ||
} | ||
if (match) { | ||
this.hostname = match[1]; | ||
this.user = match[2]; | ||
this.project = match[3]; | ||
if (this.project.endsWith(".git")) { | ||
this.project = this.project.slice(0, -4); | ||
} | ||
break; | ||
} | ||
} | ||
if (this.hostname.includes("bitbucket.org")) { | ||
this.type = models_1.RepositoryType.Bitbucket; | ||
} | ||
else if (this.hostname.includes("gitlab.com")) { | ||
this.type = models_1.RepositoryType.GitLab; | ||
} | ||
else { | ||
this.type = models_1.RepositoryType.GitHub; | ||
} | ||
let out = git("-C", path, "ls-files"); | ||
this.baseUrl = baseUrl; | ||
this.anchorPrefix = guessAnchorPrefix(this.baseUrl); | ||
const out = git("-C", path, "ls-files"); | ||
if (out.status === 0) { | ||
out.stdout.split("\n").forEach((file) => { | ||
if (file !== "") { | ||
this.files.push(base_path_1.BasePath.normalize(path + "/" + file)); | ||
this.files.add(base_path_1.BasePath.normalize(path + "/" + file)); | ||
} | ||
}); | ||
} | ||
if (!gitRevision) { | ||
out = git("-C", path, "rev-parse", "--short", "HEAD"); | ||
if (out.status === 0) { | ||
this.branch = out.stdout.replace("\n", ""); | ||
} | ||
} | ||
} | ||
/** | ||
* Check whether the given file is tracked by this repository. | ||
* | ||
* @param fileName The name of the file to test for. | ||
* @returns TRUE when the file is part of the repository, otherwise FALSE. | ||
*/ | ||
contains(fileName) { | ||
return this.files.includes(fileName); | ||
} | ||
/** | ||
* Get the URL of the given file on GitHub or Bitbucket. | ||
@@ -117,31 +49,9 @@ * | ||
getURL(fileName) { | ||
if (this.urlCache.has(fileName)) { | ||
return this.urlCache.get(fileName); | ||
} | ||
if (!this.user || !this.project || !this.contains(fileName)) { | ||
if (!this.files.has(fileName)) { | ||
return; | ||
} | ||
const url = [ | ||
`https://${this.hostname}`, | ||
this.user, | ||
this.project, | ||
this.type === models_1.RepositoryType.GitLab ? "-" : undefined, | ||
this.type === models_1.RepositoryType.Bitbucket ? "src" : "blob", | ||
this.branch, | ||
fileName.substring(this.path.length + 1), | ||
] | ||
.filter((s) => !!s) | ||
.join("/"); | ||
this.urlCache.set(fileName, url); | ||
return url; | ||
return `${this.baseUrl}/${fileName.substring(this.path.length + 1)}`; | ||
} | ||
getLineNumberAnchor(lineNumber) { | ||
switch (this.type) { | ||
default: | ||
case models_1.RepositoryType.GitHub: | ||
case models_1.RepositoryType.GitLab: | ||
return "L" + lineNumber; | ||
case models_1.RepositoryType.Bitbucket: | ||
return "lines-" + lineNumber; | ||
} | ||
return `${this.anchorPrefix}${lineNumber}`; | ||
} | ||
@@ -157,11 +67,75 @@ /** | ||
*/ | ||
static tryCreateRepository(path, gitRevision, gitRemote) { | ||
const out = git("-C", path, "rev-parse", "--show-toplevel"); | ||
const remotesOutput = git("-C", path, "remote", "get-url", gitRemote); | ||
if (out.status !== 0 || remotesOutput.status !== 0) { | ||
static tryCreateRepository(path, gitRevision, gitRemote, logger) { | ||
const topLevel = git("-C", path, "rev-parse", "--show-toplevel"); | ||
if (topLevel.status !== 0) | ||
return; | ||
gitRevision || (gitRevision = git("-C", path, "rev-parse", "--short", "HEAD").stdout.trim()); | ||
if (!gitRevision) | ||
return; // Will only happen in a repo with no commits. | ||
let baseUrl; | ||
if (/^https?:\/\//.test(gitRemote)) { | ||
baseUrl = `${gitRemote}/${gitRevision}`; | ||
} | ||
return new Repository(base_path_1.BasePath.normalize(out.stdout.replace("\n", "")), gitRevision, remotesOutput.stdout.split("\n")); | ||
else { | ||
const remotesOut = git("-C", path, "remote", "get-url", gitRemote); | ||
if (remotesOut.status === 0) { | ||
baseUrl = guessBaseUrl(gitRevision, remotesOut.stdout.split("\n")); | ||
} | ||
else { | ||
logger.warn(`The provided git remote "${gitRemote}" was not valid. Source links will be broken.`); | ||
} | ||
} | ||
if (!baseUrl) | ||
return; | ||
return new Repository(base_path_1.BasePath.normalize(topLevel.stdout.replace("\n", "")), baseUrl); | ||
} | ||
} | ||
exports.Repository = Repository; | ||
// Should have three capturing groups: | ||
// 1. hostname | ||
// 2. user | ||
// 3. project | ||
const repoExpressions = [ | ||
/(github(?!.us)(?:\.[a-z]+)*\.[a-z]{2,})[:/]([^/]+)\/(.*)/, | ||
/(\w+\.githubprivate.com)[:/]([^/]+)\/(.*)/, | ||
/(\w+\.ghe.com)[:/]([^/]+)\/(.*)/, | ||
/(\w+\.github.us)[:/]([^/]+)\/(.*)/, | ||
/(bitbucket.org)[:/]([^/]+)\/(.*)/, | ||
/(gitlab.com)[:/]([^/]+)\/(.*)/, | ||
]; | ||
function guessBaseUrl(gitRevision, remotes) { | ||
let hostname = ""; | ||
let user = ""; | ||
let project = ""; | ||
outer: for (const repoLink of remotes) { | ||
for (const regex of repoExpressions) { | ||
const match = regex.exec(repoLink); | ||
if (match) { | ||
hostname = match[1]; | ||
user = match[2]; | ||
project = match[3]; | ||
break outer; | ||
} | ||
} | ||
} | ||
if (!hostname) | ||
return; | ||
if (project.endsWith(".git")) { | ||
project = project.slice(0, -4); | ||
} | ||
let sourcePath = "blob"; | ||
if (hostname.includes("gitlab")) { | ||
sourcePath = "-/blob"; | ||
} | ||
else if (hostname.includes("bitbucket")) { | ||
sourcePath = "src"; | ||
} | ||
return `https://${hostname}/${user}/${project}/${sourcePath}/${gitRevision}`; | ||
} | ||
exports.guessBaseUrl = guessBaseUrl; | ||
function guessAnchorPrefix(url) { | ||
if (url.includes("bitbucket")) { | ||
return "lines-"; | ||
} | ||
return "L"; | ||
} |
export { SourceReference } from "./file"; | ||
export { RepositoryType } from "./repository"; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.RepositoryType = exports.SourceReference = void 0; | ||
exports.SourceReference = void 0; | ||
var file_1 = require("./file"); | ||
Object.defineProperty(exports, "SourceReference", { enumerable: true, get: function () { return file_1.SourceReference; } }); | ||
var repository_1 = require("./repository"); | ||
Object.defineProperty(exports, "RepositoryType", { enumerable: true, get: function () { return repository_1.RepositoryType; } }); |
@@ -29,2 +29,3 @@ "use strict"; | ||
const icon_1 = require("./themes/default/partials/icon"); | ||
const type_1 = require("./themes/default/partials/type"); | ||
/** | ||
@@ -136,2 +137,3 @@ * The renderer processes a {@link ProjectReflection} using a {@link Theme} instance and writes | ||
this.renderDocument(output.createPageEvent(mapping)); | ||
(0, type_1.validateStateIsClean)(mapping.url); | ||
}); | ||
@@ -138,0 +140,0 @@ this.trigger(events_1.RendererEvent.END, output); |
import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext"; | ||
import { Type } from "../../../../models"; | ||
import { JSX } from "../../../../utils"; | ||
export declare function validateStateIsClean(page: string): void; | ||
export declare function type(context: DefaultThemeRenderContext, type: Type | undefined): JSX.Element; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.type = void 0; | ||
exports.type = exports.validateStateIsClean = void 0; | ||
const models_1 = require("../../../../models"); | ||
const utils_1 = require("../../../../utils"); | ||
const lib_1 = require("../../lib"); | ||
const assert_1 = require("assert"); | ||
const EXPORTABLE = models_1.ReflectionKind.Class | | ||
@@ -54,2 +55,10 @@ models_1.ReflectionKind.Interface | | ||
} | ||
let indentationDepth = 0; | ||
function includeIndentation() { | ||
return indentationDepth > 0 ? utils_1.JSX.createElement("span", null, "\u00A0".repeat(indentationDepth * 4)) : utils_1.JSX.createElement(utils_1.JSX.Fragment, null); | ||
} | ||
function validateStateIsClean(page) { | ||
(0, assert_1.ok)(indentationDepth === 0, `Rendering ${page}: Indentation depth increment/decrement not matched: ${indentationDepth}`); | ||
} | ||
exports.validateStateIsClean = validateStateIsClean; | ||
// The type helper accepts an optional needsParens parameter that is checked | ||
@@ -196,3 +205,5 @@ // if an inner type may result in invalid output without them. For example: | ||
const members = []; | ||
for (const item of type.declaration.children || []) { | ||
const children = type.declaration.children || []; | ||
indentationDepth++; | ||
for (const item of children) { | ||
if (item.getSignature && item.setSignature) { | ||
@@ -242,2 +253,3 @@ members.push(utils_1.JSX.createElement(utils_1.JSX.Fragment, null, | ||
if (!members.length && type.declaration.signatures?.length === 1) { | ||
indentationDepth--; | ||
return (utils_1.JSX.createElement(utils_1.JSX.Fragment, null, | ||
@@ -255,4 +267,10 @@ utils_1.JSX.createElement("span", { class: "tsd-signature-symbol" }, "("), | ||
if (members.length) { | ||
const membersWithSeparators = members.flatMap((m) => [m, utils_1.JSX.createElement("span", { class: "tsd-signature-symbol" }, "; ")]); | ||
const membersWithSeparators = members.flatMap((m) => [ | ||
includeIndentation(), | ||
m, | ||
utils_1.JSX.createElement("span", { class: "tsd-signature-symbol" }, "; "), | ||
utils_1.JSX.createElement("br", null), | ||
]); | ||
membersWithSeparators.pop(); | ||
indentationDepth--; | ||
return (utils_1.JSX.createElement(utils_1.JSX.Fragment, null, | ||
@@ -262,7 +280,9 @@ utils_1.JSX.createElement("span", { class: "tsd-signature-symbol" }, | ||
" "), | ||
utils_1.JSX.createElement("br", null), | ||
membersWithSeparators, | ||
utils_1.JSX.createElement("span", { class: "tsd-signature-symbol" }, | ||
" ", | ||
"}"))); | ||
utils_1.JSX.createElement("br", null), | ||
includeIndentation(), | ||
utils_1.JSX.createElement("span", { class: "tsd-signature-symbol" }, "}"))); | ||
} | ||
indentationDepth--; | ||
return utils_1.JSX.createElement("span", { class: "tsd-signature-symbol" }, "{}"); | ||
@@ -269,0 +289,0 @@ }, |
@@ -237,3 +237,3 @@ "use strict"; | ||
} | ||
const tsconfigFile = ts.findConfigFile(packageEntryPoint, ts.sys.fileExists); | ||
const tsconfigFile = ts.findConfigFile(packageEntryPoint, ts.sys.fileExists, typedocPackageConfig?.tsconfig); | ||
if (tsconfigFile === undefined) { | ||
@@ -278,5 +278,3 @@ logger.error(`Could not determine tsconfig.json for source file ${packageEntryPoint} (it must be on an ancestor path)`); | ||
: void 0, | ||
readmeFile: typedocPackageConfig?.readmeFile | ||
? Path.resolve(Path.join(packageJsonPath, "..", typedocPackageConfig?.readmeFile)) | ||
: undefined, | ||
readmeFile: discoverReadmeFile(logger, Path.join(packageJsonPath, ".."), typedocPackageConfig?.readmeFile), | ||
program, | ||
@@ -288,1 +286,15 @@ sourceFile, | ||
} | ||
function discoverReadmeFile(logger, packageDir, userReadme) { | ||
if (userReadme) { | ||
if (!FS.existsSync(Path.join(packageDir, userReadme))) { | ||
logger.warn(`Failed to find ${userReadme} in ${(0, paths_1.nicePath)(packageDir)}`); | ||
return; | ||
} | ||
return Path.resolve(Path.join(packageDir, userReadme)); | ||
} | ||
for (const file of FS.readdirSync(packageDir)) { | ||
if (file.toLowerCase() === "readme.md") { | ||
return Path.resolve(Path.join(packageDir, file)); | ||
} | ||
} | ||
} |
@@ -12,2 +12,3 @@ import type { Logger } from "./loggers"; | ||
readmeFile: import("./validation").Optional<StringConstructor>; | ||
tsconfig: import("./validation").Optional<StringConstructor>; | ||
[additionalProperties]: boolean; | ||
@@ -14,0 +15,0 @@ }; |
@@ -35,2 +35,3 @@ "use strict"; | ||
readmeFile: (0, validation_1.optional)(String), | ||
tsconfig: (0, validation_1.optional)(String), | ||
[validation_1.additionalProperties]: false, | ||
@@ -37,0 +38,0 @@ }; |
{ | ||
"name": "typedoc", | ||
"description": "Create api documentation for TypeScript projects.", | ||
"version": "0.23.15", | ||
"version": "0.23.16", | ||
"homepage": "https://typedoc.org", | ||
@@ -6,0 +6,0 @@ "main": "./dist/index.js", |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1021023
289
24117
313
5
1
28