typedoc 0.23.15 → 0.23.17
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.
- package/dist/lib/converter/plugins/SourcePlugin.d.ts +1 -0
- package/dist/lib/converter/plugins/SourcePlugin.js +5 -5
- package/dist/lib/converter/symbols.js +6 -3
- package/dist/lib/converter/utils/repository.d.ts +10 -41
- package/dist/lib/converter/utils/repository.js +85 -109
- package/dist/lib/models/sources/index.d.ts +0 -1
- package/dist/lib/models/sources/index.js +1 -3
- package/dist/lib/output/renderer.js +2 -0
- package/dist/lib/output/themes/default/DefaultThemeRenderContext.d.ts +1 -0
- package/dist/lib/output/themes/default/DefaultThemeRenderContext.js +1 -0
- package/dist/lib/output/themes/default/partials/navigation.d.ts +1 -0
- package/dist/lib/output/themes/default/partials/navigation.js +9 -1
- package/dist/lib/output/themes/default/partials/toolbar.js +5 -3
- package/dist/lib/output/themes/default/partials/type.d.ts +1 -0
- package/dist/lib/output/themes/default/partials/type.js +26 -6
- package/dist/lib/utils/entry-point.js +16 -4
- package/dist/lib/utils/options/declaration.d.ts +4 -0
- package/dist/lib/utils/options/sources/typedoc.js +37 -0
- package/dist/lib/utils/package-manifest.d.ts +1 -0
- package/dist/lib/utils/package-manifest.js +1 -0
- package/package.json +1 -1
- package/static/style.css +34 -2
- package/dist/lib/models/sources/repository.d.ts +0 -5
- package/dist/lib/models/sources/repository.js +0 -9
|
@@ -6,6 +6,7 @@ export declare class SourcePlugin extends ConverterComponent {
|
|
|
6
6
|
readonly disableSources: boolean;
|
|
7
7
|
readonly gitRevision: string;
|
|
8
8
|
readonly gitRemote: string;
|
|
9
|
+
readonly sourceLinkTemplate: string;
|
|
9
10
|
readonly basePath: string;
|
|
10
11
|
/**
|
|
11
12
|
* All file names to find the base path from.
|
|
@@ -100,10 +100,7 @@ let SourcePlugin = class SourcePlugin extends components_1.ConverterComponent {
|
|
|
100
100
|
for (const source of refl.sources || []) {
|
|
101
101
|
if (repository_1.gitIsInstalled) {
|
|
102
102
|
const repo = this.getRepository(source.fullFileName);
|
|
103
|
-
source.url = repo?.getURL(source.fullFileName);
|
|
104
|
-
if (source.url) {
|
|
105
|
-
source.url += `#${repo.getLineNumberAnchor(source.line)}`;
|
|
106
|
-
}
|
|
103
|
+
source.url = repo?.getURL(source.fullFileName, source.line);
|
|
107
104
|
}
|
|
108
105
|
source.fileName = (0, fs_1.normalizePath)((0, path_1.relative)(basePath, source.fullFileName));
|
|
109
106
|
}
|
|
@@ -131,7 +128,7 @@ let SourcePlugin = class SourcePlugin extends components_1.ConverterComponent {
|
|
|
131
128
|
}
|
|
132
129
|
}
|
|
133
130
|
// Try to create a new repository
|
|
134
|
-
const repository = repository_1.Repository.tryCreateRepository(dirName, this.gitRevision, this.gitRemote);
|
|
131
|
+
const repository = repository_1.Repository.tryCreateRepository(dirName, this.sourceLinkTemplate, this.gitRevision, this.gitRemote, this.application.logger);
|
|
135
132
|
if (repository) {
|
|
136
133
|
this.repositories[repository.path.toLowerCase()] = repository;
|
|
137
134
|
return repository;
|
|
@@ -149,6 +146,9 @@ __decorate([
|
|
|
149
146
|
__decorate([
|
|
150
147
|
(0, utils_1.BindOption)("gitRemote")
|
|
151
148
|
], SourcePlugin.prototype, "gitRemote", void 0);
|
|
149
|
+
__decorate([
|
|
150
|
+
(0, utils_1.BindOption)("sourceLinkTemplate")
|
|
151
|
+
], SourcePlugin.prototype, "sourceLinkTemplate", void 0);
|
|
152
152
|
__decorate([
|
|
153
153
|
(0, utils_1.BindOption)("basePath")
|
|
154
154
|
], SourcePlugin.prototype, "basePath", void 0);
|
|
@@ -512,9 +512,12 @@ function convertAccessor(context, symbol, exportSymbol) {
|
|
|
512
512
|
function isInherited(context, symbol) {
|
|
513
513
|
const parentSymbol = context.project.getSymbolFromReflection(context.scope);
|
|
514
514
|
assert(parentSymbol, `No parent symbol found for ${symbol.name} in ${context.scope.name}`);
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
515
|
+
const parents = parentSymbol.declarations?.slice() || [];
|
|
516
|
+
const constructorDecls = parents.flatMap((parent) => ts.isClassDeclaration(parent)
|
|
517
|
+
? parent.members.filter(ts.isConstructorDeclaration)
|
|
518
|
+
: []);
|
|
519
|
+
parents.push(...constructorDecls);
|
|
520
|
+
return (parents.some((d) => symbol.getDeclarations()?.some((d2) => d2.parent === d)) === false);
|
|
518
521
|
}
|
|
519
522
|
function setModifiers(symbol, declaration, reflection) {
|
|
520
523
|
if (!declaration) {
|
|
@@ -1,64 +1,32 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { Logger } from "../../utils";
|
|
2
2
|
export declare const gitIsInstalled: boolean;
|
|
3
3
|
/**
|
|
4
4
|
* Stores data of a repository.
|
|
5
5
|
*/
|
|
6
6
|
export declare class Repository {
|
|
7
7
|
/**
|
|
8
|
-
* The
|
|
8
|
+
* The path of this repository on disk.
|
|
9
9
|
*/
|
|
10
10
|
path: string;
|
|
11
11
|
/**
|
|
12
|
-
*
|
|
12
|
+
* All files tracked by the repository.
|
|
13
13
|
*/
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
*/
|
|
18
|
-
files: string[];
|
|
19
|
-
/**
|
|
20
|
-
* The user/organization name of this repository on GitHub.
|
|
21
|
-
*/
|
|
22
|
-
user?: string;
|
|
23
|
-
/**
|
|
24
|
-
* The project name of this repository on GitHub.
|
|
25
|
-
*/
|
|
26
|
-
project?: string;
|
|
27
|
-
/**
|
|
28
|
-
* The hostname for this GitHub/Bitbucket/.etc project.
|
|
29
|
-
*
|
|
30
|
-
* Defaults to: `github.com` (for normal, public GitHub instance projects)
|
|
31
|
-
*
|
|
32
|
-
* Can be the hostname for an enterprise version of GitHub, e.g. `github.acme.com`
|
|
33
|
-
* (if found as a match in the list of git remotes).
|
|
34
|
-
*/
|
|
35
|
-
hostname: string;
|
|
36
|
-
/**
|
|
37
|
-
* Whether this is a GitHub, Bitbucket, or other type of repository.
|
|
38
|
-
*/
|
|
39
|
-
type: RepositoryType;
|
|
40
|
-
private urlCache;
|
|
14
|
+
files: Set<string>;
|
|
15
|
+
urlTemplate: string;
|
|
16
|
+
gitRevision: string;
|
|
41
17
|
/**
|
|
42
18
|
* Create a new Repository instance.
|
|
43
19
|
*
|
|
44
20
|
* @param path The root path of the repository.
|
|
45
21
|
*/
|
|
46
|
-
constructor(path: string, gitRevision: string,
|
|
47
|
-
/**
|
|
48
|
-
* Check whether the given file is tracked by this repository.
|
|
49
|
-
*
|
|
50
|
-
* @param fileName The name of the file to test for.
|
|
51
|
-
* @returns TRUE when the file is part of the repository, otherwise FALSE.
|
|
52
|
-
*/
|
|
53
|
-
contains(fileName: string): boolean;
|
|
22
|
+
constructor(path: string, gitRevision: string, urlTemplate: string);
|
|
54
23
|
/**
|
|
55
24
|
* Get the URL of the given file on GitHub or Bitbucket.
|
|
56
25
|
*
|
|
57
26
|
* @param fileName The file whose URL should be determined.
|
|
58
27
|
* @returns A URL pointing to the web preview of the given file or undefined.
|
|
59
28
|
*/
|
|
60
|
-
getURL(fileName: string): string | undefined;
|
|
61
|
-
getLineNumberAnchor(lineNumber: number): string;
|
|
29
|
+
getURL(fileName: string, line: number): string | undefined;
|
|
62
30
|
/**
|
|
63
31
|
* Try to create a new repository instance.
|
|
64
32
|
*
|
|
@@ -68,5 +36,6 @@ export declare class Repository {
|
|
|
68
36
|
* @param path The potential repository root.
|
|
69
37
|
* @returns A new instance of {@link Repository} or undefined.
|
|
70
38
|
*/
|
|
71
|
-
static tryCreateRepository(path: string, gitRevision: string, gitRemote: string): Repository | undefined;
|
|
39
|
+
static tryCreateRepository(path: string, sourceLinkTemplate: string, gitRevision: string, gitRemote: string, logger: Logger): Repository | undefined;
|
|
72
40
|
}
|
|
41
|
+
export declare function guessSourceUrlTemplate(remotes: string[]): string | undefined;
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Repository = exports.gitIsInstalled = void 0;
|
|
3
|
+
exports.guessSourceUrlTemplate = exports.Repository = exports.gitIsInstalled = void 0;
|
|
4
4
|
const child_process_1 = require("child_process");
|
|
5
|
-
const models_1 = require("../../models");
|
|
6
5
|
const base_path_1 = require("../utils/base-path");
|
|
7
6
|
const TEN_MEGABYTES = 1024 * 10000;
|
|
8
7
|
function git(...args) {
|
|
@@ -22,89 +21,22 @@ class Repository {
|
|
|
22
21
|
*
|
|
23
22
|
* @param path The root path of the repository.
|
|
24
23
|
*/
|
|
25
|
-
constructor(path, gitRevision,
|
|
24
|
+
constructor(path, gitRevision, urlTemplate) {
|
|
26
25
|
/**
|
|
27
|
-
*
|
|
26
|
+
* All files tracked by the repository.
|
|
28
27
|
*/
|
|
29
|
-
this.files =
|
|
30
|
-
/**
|
|
31
|
-
* The hostname for this GitHub/Bitbucket/.etc project.
|
|
32
|
-
*
|
|
33
|
-
* Defaults to: `github.com` (for normal, public GitHub instance projects)
|
|
34
|
-
*
|
|
35
|
-
* Can be the hostname for an enterprise version of GitHub, e.g. `github.acme.com`
|
|
36
|
-
* (if found as a match in the list of git remotes).
|
|
37
|
-
*/
|
|
38
|
-
this.hostname = "github.com";
|
|
39
|
-
/**
|
|
40
|
-
* Whether this is a GitHub, Bitbucket, or other type of repository.
|
|
41
|
-
*/
|
|
42
|
-
this.type = models_1.RepositoryType.GitHub;
|
|
43
|
-
this.urlCache = new Map();
|
|
28
|
+
this.files = new Set();
|
|
44
29
|
this.path = path;
|
|
45
|
-
this.
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
// Github Enterprise
|
|
49
|
-
if (!match) {
|
|
50
|
-
match = /(\w+\.githubprivate.com)[:/]([^/]+)\/(.*)/.exec(repoLinks[i]);
|
|
51
|
-
}
|
|
52
|
-
// Github Enterprise
|
|
53
|
-
if (!match) {
|
|
54
|
-
match = /(\w+\.ghe.com)[:/]([^/]+)\/(.*)/.exec(repoLinks[i]);
|
|
55
|
-
}
|
|
56
|
-
// Github Enterprise
|
|
57
|
-
if (!match) {
|
|
58
|
-
match = /(\w+\.github.us)[:/]([^/]+)\/(.*)/.exec(repoLinks[i]);
|
|
59
|
-
}
|
|
60
|
-
if (!match) {
|
|
61
|
-
match = /(bitbucket.org)[:/]([^/]+)\/(.*)/.exec(repoLinks[i]);
|
|
62
|
-
}
|
|
63
|
-
if (!match) {
|
|
64
|
-
match = /(gitlab.com)[:/]([^/]+)\/(.*)/.exec(repoLinks[i]);
|
|
65
|
-
}
|
|
66
|
-
if (match) {
|
|
67
|
-
this.hostname = match[1];
|
|
68
|
-
this.user = match[2];
|
|
69
|
-
this.project = match[3];
|
|
70
|
-
if (this.project.endsWith(".git")) {
|
|
71
|
-
this.project = this.project.slice(0, -4);
|
|
72
|
-
}
|
|
73
|
-
break;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
if (this.hostname.includes("bitbucket.org")) {
|
|
77
|
-
this.type = models_1.RepositoryType.Bitbucket;
|
|
78
|
-
}
|
|
79
|
-
else if (this.hostname.includes("gitlab.com")) {
|
|
80
|
-
this.type = models_1.RepositoryType.GitLab;
|
|
81
|
-
}
|
|
82
|
-
else {
|
|
83
|
-
this.type = models_1.RepositoryType.GitHub;
|
|
84
|
-
}
|
|
85
|
-
let out = git("-C", path, "ls-files");
|
|
30
|
+
this.gitRevision = gitRevision;
|
|
31
|
+
this.urlTemplate = urlTemplate;
|
|
32
|
+
const out = git("-C", path, "ls-files");
|
|
86
33
|
if (out.status === 0) {
|
|
87
34
|
out.stdout.split("\n").forEach((file) => {
|
|
88
35
|
if (file !== "") {
|
|
89
|
-
this.files.
|
|
36
|
+
this.files.add(base_path_1.BasePath.normalize(path + "/" + file));
|
|
90
37
|
}
|
|
91
38
|
});
|
|
92
39
|
}
|
|
93
|
-
if (!gitRevision) {
|
|
94
|
-
out = git("-C", path, "rev-parse", "--short", "HEAD");
|
|
95
|
-
if (out.status === 0) {
|
|
96
|
-
this.branch = out.stdout.replace("\n", "");
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
/**
|
|
101
|
-
* Check whether the given file is tracked by this repository.
|
|
102
|
-
*
|
|
103
|
-
* @param fileName The name of the file to test for.
|
|
104
|
-
* @returns TRUE when the file is part of the repository, otherwise FALSE.
|
|
105
|
-
*/
|
|
106
|
-
contains(fileName) {
|
|
107
|
-
return this.files.includes(fileName);
|
|
108
40
|
}
|
|
109
41
|
/**
|
|
110
42
|
* Get the URL of the given file on GitHub or Bitbucket.
|
|
@@ -112,36 +44,16 @@ class Repository {
|
|
|
112
44
|
* @param fileName The file whose URL should be determined.
|
|
113
45
|
* @returns A URL pointing to the web preview of the given file or undefined.
|
|
114
46
|
*/
|
|
115
|
-
getURL(fileName) {
|
|
116
|
-
if (this.
|
|
117
|
-
return this.urlCache.get(fileName);
|
|
118
|
-
}
|
|
119
|
-
if (!this.user || !this.project || !this.contains(fileName)) {
|
|
47
|
+
getURL(fileName, line) {
|
|
48
|
+
if (!this.files.has(fileName)) {
|
|
120
49
|
return;
|
|
121
50
|
}
|
|
122
|
-
const
|
|
123
|
-
|
|
124
|
-
this.
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
this.branch,
|
|
129
|
-
fileName.substring(this.path.length + 1),
|
|
130
|
-
]
|
|
131
|
-
.filter((s) => !!s)
|
|
132
|
-
.join("/");
|
|
133
|
-
this.urlCache.set(fileName, url);
|
|
134
|
-
return url;
|
|
135
|
-
}
|
|
136
|
-
getLineNumberAnchor(lineNumber) {
|
|
137
|
-
switch (this.type) {
|
|
138
|
-
default:
|
|
139
|
-
case models_1.RepositoryType.GitHub:
|
|
140
|
-
case models_1.RepositoryType.GitLab:
|
|
141
|
-
return "L" + lineNumber;
|
|
142
|
-
case models_1.RepositoryType.Bitbucket:
|
|
143
|
-
return "lines-" + lineNumber;
|
|
144
|
-
}
|
|
51
|
+
const replacements = {
|
|
52
|
+
gitRevision: this.gitRevision,
|
|
53
|
+
path: fileName.substring(this.path.length + 1),
|
|
54
|
+
line,
|
|
55
|
+
};
|
|
56
|
+
return this.urlTemplate.replace(/\{(gitRevision|path|line)\}/g, (_, key) => replacements[key]);
|
|
145
57
|
}
|
|
146
58
|
/**
|
|
147
59
|
* Try to create a new repository instance.
|
|
@@ -152,13 +64,77 @@ class Repository {
|
|
|
152
64
|
* @param path The potential repository root.
|
|
153
65
|
* @returns A new instance of {@link Repository} or undefined.
|
|
154
66
|
*/
|
|
155
|
-
static tryCreateRepository(path, gitRevision, gitRemote) {
|
|
156
|
-
const
|
|
157
|
-
|
|
158
|
-
if (out.status !== 0 || remotesOutput.status !== 0) {
|
|
67
|
+
static tryCreateRepository(path, sourceLinkTemplate, gitRevision, gitRemote, logger) {
|
|
68
|
+
const topLevel = git("-C", path, "rev-parse", "--show-toplevel");
|
|
69
|
+
if (topLevel.status !== 0)
|
|
159
70
|
return;
|
|
71
|
+
gitRevision || (gitRevision = git("-C", path, "rev-parse", "--short", "HEAD").stdout.trim());
|
|
72
|
+
if (!gitRevision)
|
|
73
|
+
return; // Will only happen in a repo with no commits.
|
|
74
|
+
let urlTemplate;
|
|
75
|
+
if (sourceLinkTemplate) {
|
|
76
|
+
urlTemplate = sourceLinkTemplate;
|
|
77
|
+
}
|
|
78
|
+
else if (/^https?:\/\//.test(gitRemote)) {
|
|
79
|
+
logger.warn("Using a link as the gitRemote is deprecated and will be removed in 0.24.");
|
|
80
|
+
urlTemplate = `${gitRemote}/{gitRevision}`;
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
const remotesOut = git("-C", path, "remote", "get-url", gitRemote);
|
|
84
|
+
if (remotesOut.status === 0) {
|
|
85
|
+
urlTemplate = guessSourceUrlTemplate(remotesOut.stdout.split("\n"));
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
logger.warn(`The provided git remote "${gitRemote}" was not valid. Source links will be broken.`);
|
|
89
|
+
}
|
|
160
90
|
}
|
|
161
|
-
|
|
91
|
+
if (!urlTemplate)
|
|
92
|
+
return;
|
|
93
|
+
return new Repository(base_path_1.BasePath.normalize(topLevel.stdout.replace("\n", "")), gitRevision, urlTemplate);
|
|
162
94
|
}
|
|
163
95
|
}
|
|
164
96
|
exports.Repository = Repository;
|
|
97
|
+
// Should have three capturing groups:
|
|
98
|
+
// 1. hostname
|
|
99
|
+
// 2. user
|
|
100
|
+
// 3. project
|
|
101
|
+
const repoExpressions = [
|
|
102
|
+
/(github(?!.us)(?:\.[a-z]+)*\.[a-z]{2,})[:/]([^/]+)\/(.*)/,
|
|
103
|
+
/(\w+\.githubprivate.com)[:/]([^/]+)\/(.*)/,
|
|
104
|
+
/(\w+\.ghe.com)[:/]([^/]+)\/(.*)/,
|
|
105
|
+
/(\w+\.github.us)[:/]([^/]+)\/(.*)/,
|
|
106
|
+
/(bitbucket.org)[:/]([^/]+)\/(.*)/,
|
|
107
|
+
/(gitlab.com)[:/]([^/]+)\/(.*)/,
|
|
108
|
+
];
|
|
109
|
+
function guessSourceUrlTemplate(remotes) {
|
|
110
|
+
let hostname = "";
|
|
111
|
+
let user = "";
|
|
112
|
+
let project = "";
|
|
113
|
+
outer: for (const repoLink of remotes) {
|
|
114
|
+
for (const regex of repoExpressions) {
|
|
115
|
+
const match = regex.exec(repoLink);
|
|
116
|
+
if (match) {
|
|
117
|
+
hostname = match[1];
|
|
118
|
+
user = match[2];
|
|
119
|
+
project = match[3];
|
|
120
|
+
break outer;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
if (!hostname)
|
|
125
|
+
return;
|
|
126
|
+
if (project.endsWith(".git")) {
|
|
127
|
+
project = project.slice(0, -4);
|
|
128
|
+
}
|
|
129
|
+
let sourcePath = "blob";
|
|
130
|
+
let anchorPrefix = "L";
|
|
131
|
+
if (hostname.includes("gitlab")) {
|
|
132
|
+
sourcePath = "-/blob";
|
|
133
|
+
}
|
|
134
|
+
else if (hostname.includes("bitbucket")) {
|
|
135
|
+
sourcePath = "src";
|
|
136
|
+
anchorPrefix = "lines-";
|
|
137
|
+
}
|
|
138
|
+
return `https://${hostname}/${user}/${project}/${sourcePath}/{gitRevision}/{path}#${anchorPrefix}{line}`;
|
|
139
|
+
}
|
|
140
|
+
exports.guessSourceUrlTemplate = guessSourceUrlTemplate;
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.SourceReference = void 0;
|
|
4
4
|
var file_1 = require("./file");
|
|
5
5
|
Object.defineProperty(exports, "SourceReference", { enumerable: true, get: function () { return file_1.SourceReference; } });
|
|
6
|
-
var repository_1 = require("./repository");
|
|
7
|
-
Object.defineProperty(exports, "RepositoryType", { enumerable: true, get: function () { return repository_1.RepositoryType; } });
|
|
@@ -26,6 +26,7 @@ const utils_1 = require("../utils");
|
|
|
26
26
|
const highlighter_1 = require("../utils/highlighter");
|
|
27
27
|
const models_1 = require("../models");
|
|
28
28
|
const icon_1 = require("./themes/default/partials/icon");
|
|
29
|
+
const type_1 = require("./themes/default/partials/type");
|
|
29
30
|
/**
|
|
30
31
|
* The renderer processes a {@link ProjectReflection} using a {@link Theme} instance and writes
|
|
31
32
|
* the emitted html documents to a output directory. You can specify which theme should be used
|
|
@@ -132,6 +133,7 @@ let Renderer = class Renderer extends component_1.ChildableComponent {
|
|
|
132
133
|
output.urls.forEach((mapping) => {
|
|
133
134
|
(0, icon_1.clearSeenIconCache)();
|
|
134
135
|
this.renderDocument(output.createPageEvent(mapping));
|
|
136
|
+
(0, type_1.validateStateIsClean)(mapping.url);
|
|
135
137
|
});
|
|
136
138
|
this.trigger(events_1.RendererEvent.END, output);
|
|
137
139
|
}
|
|
@@ -44,6 +44,7 @@ export declare class DefaultThemeRenderContext {
|
|
|
44
44
|
members: (props: import("../../../models").ContainerReflection) => import("../../../utils/jsx.elements").JsxElement;
|
|
45
45
|
membersGroup: (group: import("../../../models").ReflectionGroup) => import("../../../utils/jsx.elements").JsxElement;
|
|
46
46
|
navigation: (props: import("../..").PageEvent<Reflection>) => import("../../../utils/jsx.elements").JsxElement;
|
|
47
|
+
sidebarLinks: () => import("../../../utils/jsx.elements").JsxElement | null;
|
|
47
48
|
settings: () => import("../../../utils/jsx.elements").JsxElement;
|
|
48
49
|
primaryNavigation: (props: import("../..").PageEvent<Reflection>) => import("../../../utils/jsx.elements").JsxElement;
|
|
49
50
|
secondaryNavigation: (props: import("../..").PageEvent<Reflection>) => import("../../../utils/jsx.elements").JsxElement | undefined;
|
|
@@ -77,6 +77,7 @@ class DefaultThemeRenderContext {
|
|
|
77
77
|
this.members = bind(members_1.members, this);
|
|
78
78
|
this.membersGroup = bind(members_group_1.membersGroup, this);
|
|
79
79
|
this.navigation = bind(navigation_1.navigation, this);
|
|
80
|
+
this.sidebarLinks = bind(navigation_1.sidebarLinks, this);
|
|
80
81
|
this.settings = bind(navigation_1.settings, this);
|
|
81
82
|
this.primaryNavigation = bind(navigation_1.primaryNavigation, this);
|
|
82
83
|
this.secondaryNavigation = bind(navigation_1.secondaryNavigation, this);
|
|
@@ -3,6 +3,7 @@ import { JSX } from "../../../../utils";
|
|
|
3
3
|
import type { PageEvent } from "../../../events";
|
|
4
4
|
import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext";
|
|
5
5
|
export declare function navigation(context: DefaultThemeRenderContext, props: PageEvent<Reflection>): JSX.Element;
|
|
6
|
+
export declare function sidebarLinks(context: DefaultThemeRenderContext): JSX.Element | null;
|
|
6
7
|
export declare function settings(context: DefaultThemeRenderContext): JSX.Element;
|
|
7
8
|
export declare function primaryNavigation(context: DefaultThemeRenderContext, props: PageEvent<Reflection>): JSX.Element;
|
|
8
9
|
export declare function secondaryNavigation(context: DefaultThemeRenderContext, props: PageEvent<Reflection>): JSX.Element | undefined;
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.secondaryNavigation = exports.primaryNavigation = exports.settings = exports.navigation = void 0;
|
|
3
|
+
exports.secondaryNavigation = exports.primaryNavigation = exports.settings = exports.sidebarLinks = exports.navigation = void 0;
|
|
4
4
|
const models_1 = require("../../../../models");
|
|
5
5
|
const utils_1 = require("../../../../utils");
|
|
6
6
|
const lib_1 = require("../../lib");
|
|
7
7
|
function navigation(context, props) {
|
|
8
8
|
return (utils_1.JSX.createElement(utils_1.JSX.Fragment, null,
|
|
9
|
+
context.sidebarLinks(),
|
|
9
10
|
context.settings(),
|
|
10
11
|
context.primaryNavigation(props),
|
|
11
12
|
context.secondaryNavigation(props)));
|
|
@@ -18,6 +19,13 @@ function buildFilterItem(context, name, displayName, defaultValue) {
|
|
|
18
19
|
context.icons.checkbox(),
|
|
19
20
|
utils_1.JSX.createElement("span", null, displayName))));
|
|
20
21
|
}
|
|
22
|
+
function sidebarLinks(context) {
|
|
23
|
+
const links = Object.entries(context.options.getValue("sidebarLinks"));
|
|
24
|
+
if (!links.length)
|
|
25
|
+
return null;
|
|
26
|
+
return (utils_1.JSX.createElement("nav", { id: "tsd-sidebar-links", class: "tsd-navigation" }, links.map(([label, url]) => (utils_1.JSX.createElement("a", { href: url, target: "_blank" }, label)))));
|
|
27
|
+
}
|
|
28
|
+
exports.sidebarLinks = sidebarLinks;
|
|
21
29
|
function settings(context) {
|
|
22
30
|
const defaultFilters = context.options.getValue("visibilityFilters");
|
|
23
31
|
const visibilityOptions = [];
|
|
@@ -6,12 +6,14 @@ const toolbar = (context, props) => (utils_1.JSX.createElement("header", { class
|
|
|
6
6
|
utils_1.JSX.createElement("div", { class: "tsd-toolbar-contents container" },
|
|
7
7
|
utils_1.JSX.createElement("div", { class: "table-cell", id: "tsd-search", "data-base": context.relativeURL("./") },
|
|
8
8
|
utils_1.JSX.createElement("div", { class: "field" },
|
|
9
|
-
utils_1.JSX.createElement("label", { for: "tsd-search-field", class: "tsd-widget search no-caption" }, context.icons.search()),
|
|
9
|
+
utils_1.JSX.createElement("label", { for: "tsd-search-field", class: "tsd-widget tsd-toolbar-icon search no-caption" }, context.icons.search()),
|
|
10
10
|
utils_1.JSX.createElement("input", { type: "text", id: "tsd-search-field", "aria-label": "Search" })),
|
|
11
|
+
utils_1.JSX.createElement("div", { class: "field" },
|
|
12
|
+
utils_1.JSX.createElement("div", { id: "tsd-toolbar-links" }, Object.entries(context.options.getValue("navigationLinks")).map(([label, url]) => (utils_1.JSX.createElement("a", { href: url }, label))))),
|
|
11
13
|
utils_1.JSX.createElement("ul", { class: "results" },
|
|
12
14
|
utils_1.JSX.createElement("li", { class: "state loading" }, "Preparing search index..."),
|
|
13
15
|
utils_1.JSX.createElement("li", { class: "state failure" }, "The search index is not available")),
|
|
14
|
-
utils_1.JSX.createElement("a", { href: context.relativeURL("index.html"), class: "title" }, props.project.name)),
|
|
16
|
+
utils_1.JSX.createElement("a", { href: context.options.getValue("titleLink") ?? context.relativeURL("index.html"), class: "title" }, props.project.name)),
|
|
15
17
|
utils_1.JSX.createElement("div", { class: "table-cell", id: "tsd-widgets" },
|
|
16
|
-
utils_1.JSX.createElement("a", { href: "#", class: "tsd-widget menu no-caption", "data-toggle": "menu", "aria-label": "Menu" }, context.icons.menu())))));
|
|
18
|
+
utils_1.JSX.createElement("a", { href: "#", class: "tsd-widget tsd-toolbar-icon menu no-caption", "data-toggle": "menu", "aria-label": "Menu" }, context.icons.menu())))));
|
|
17
19
|
exports.toolbar = toolbar;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext";
|
|
2
2
|
import { Type } from "../../../../models";
|
|
3
3
|
import { JSX } from "../../../../utils";
|
|
4
|
+
export declare function validateStateIsClean(page: string): void;
|
|
4
5
|
export declare function type(context: DefaultThemeRenderContext, type: Type | undefined): JSX.Element;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.type = void 0;
|
|
3
|
+
exports.type = exports.validateStateIsClean = void 0;
|
|
4
4
|
const models_1 = require("../../../../models");
|
|
5
5
|
const utils_1 = require("../../../../utils");
|
|
6
6
|
const lib_1 = require("../../lib");
|
|
7
|
+
const assert_1 = require("assert");
|
|
7
8
|
const EXPORTABLE = models_1.ReflectionKind.Class |
|
|
8
9
|
models_1.ReflectionKind.Interface |
|
|
9
10
|
models_1.ReflectionKind.Enum |
|
|
@@ -51,6 +52,14 @@ function getNamespacedPath(reflection) {
|
|
|
51
52
|
function renderUniquePath(context, reflection) {
|
|
52
53
|
return (0, lib_1.join)(utils_1.JSX.createElement("span", { class: "tsd-signature-symbol" }, "."), getUniquePath(reflection), (item) => (utils_1.JSX.createElement("a", { href: context.urlTo(item), class: "tsd-signature-type", "data-tsd-kind": item.kindString }, item.name)));
|
|
53
54
|
}
|
|
55
|
+
let indentationDepth = 0;
|
|
56
|
+
function includeIndentation() {
|
|
57
|
+
return indentationDepth > 0 ? utils_1.JSX.createElement("span", null, "\u00A0".repeat(indentationDepth * 4)) : utils_1.JSX.createElement(utils_1.JSX.Fragment, null);
|
|
58
|
+
}
|
|
59
|
+
function validateStateIsClean(page) {
|
|
60
|
+
(0, assert_1.ok)(indentationDepth === 0, `Rendering ${page}: Indentation depth increment/decrement not matched: ${indentationDepth}`);
|
|
61
|
+
}
|
|
62
|
+
exports.validateStateIsClean = validateStateIsClean;
|
|
54
63
|
// The type helper accepts an optional needsParens parameter that is checked
|
|
55
64
|
// if an inner type may result in invalid output without them. For example:
|
|
56
65
|
// 1 | 2[] !== (1 | 2)[]
|
|
@@ -192,7 +201,9 @@ const typeRenderers = {
|
|
|
192
201
|
},
|
|
193
202
|
reflection(context, type) {
|
|
194
203
|
const members = [];
|
|
195
|
-
|
|
204
|
+
const children = type.declaration.children || [];
|
|
205
|
+
indentationDepth++;
|
|
206
|
+
for (const item of children) {
|
|
196
207
|
if (item.getSignature && item.setSignature) {
|
|
197
208
|
members.push(utils_1.JSX.createElement(utils_1.JSX.Fragment, null,
|
|
198
209
|
item.name,
|
|
@@ -237,6 +248,7 @@ const typeRenderers = {
|
|
|
237
248
|
renderType(context, index.type, models_1.TypeContext.none)));
|
|
238
249
|
}
|
|
239
250
|
if (!members.length && type.declaration.signatures?.length === 1) {
|
|
251
|
+
indentationDepth--;
|
|
240
252
|
return (utils_1.JSX.createElement(utils_1.JSX.Fragment, null,
|
|
241
253
|
utils_1.JSX.createElement("span", { class: "tsd-signature-symbol" }, "("),
|
|
242
254
|
context.memberSignatureTitle(type.declaration.signatures[0], {
|
|
@@ -249,17 +261,25 @@ const typeRenderers = {
|
|
|
249
261
|
members.push(context.memberSignatureTitle(item, { hideName: true }));
|
|
250
262
|
}
|
|
251
263
|
if (members.length) {
|
|
252
|
-
const membersWithSeparators = members.flatMap((m) => [
|
|
264
|
+
const membersWithSeparators = members.flatMap((m) => [
|
|
265
|
+
includeIndentation(),
|
|
266
|
+
m,
|
|
267
|
+
utils_1.JSX.createElement("span", { class: "tsd-signature-symbol" }, "; "),
|
|
268
|
+
utils_1.JSX.createElement("br", null),
|
|
269
|
+
]);
|
|
253
270
|
membersWithSeparators.pop();
|
|
271
|
+
indentationDepth--;
|
|
254
272
|
return (utils_1.JSX.createElement(utils_1.JSX.Fragment, null,
|
|
255
273
|
utils_1.JSX.createElement("span", { class: "tsd-signature-symbol" },
|
|
256
274
|
"{",
|
|
257
275
|
" "),
|
|
276
|
+
utils_1.JSX.createElement("br", null),
|
|
258
277
|
membersWithSeparators,
|
|
259
|
-
utils_1.JSX.createElement("
|
|
260
|
-
|
|
261
|
-
|
|
278
|
+
utils_1.JSX.createElement("br", null),
|
|
279
|
+
includeIndentation(),
|
|
280
|
+
utils_1.JSX.createElement("span", { class: "tsd-signature-symbol" }, "}")));
|
|
262
281
|
}
|
|
282
|
+
indentationDepth--;
|
|
263
283
|
return utils_1.JSX.createElement("span", { class: "tsd-signature-symbol" }, "{}");
|
|
264
284
|
},
|
|
265
285
|
rest(context, type) {
|
|
@@ -234,7 +234,7 @@ function getEntryPointsForPackages(logger, packageGlobPaths, options) {
|
|
|
234
234
|
if (packageEntryPoint === package_manifest_1.ignorePackage) {
|
|
235
235
|
continue;
|
|
236
236
|
}
|
|
237
|
-
const tsconfigFile = ts.findConfigFile(packageEntryPoint, ts.sys.fileExists);
|
|
237
|
+
const tsconfigFile = ts.findConfigFile(packageEntryPoint, ts.sys.fileExists, typedocPackageConfig?.tsconfig);
|
|
238
238
|
if (tsconfigFile === undefined) {
|
|
239
239
|
logger.error(`Could not determine tsconfig.json for source file ${packageEntryPoint} (it must be on an ancestor path)`);
|
|
240
240
|
return;
|
|
@@ -274,12 +274,24 @@ function getEntryPointsForPackages(logger, packageGlobPaths, options) {
|
|
|
274
274
|
version: includeVersion
|
|
275
275
|
? packageJson["version"]
|
|
276
276
|
: void 0,
|
|
277
|
-
readmeFile: typedocPackageConfig?.readmeFile
|
|
278
|
-
? Path.resolve(Path.join(packageJsonPath, "..", typedocPackageConfig?.readmeFile))
|
|
279
|
-
: undefined,
|
|
277
|
+
readmeFile: discoverReadmeFile(logger, Path.join(packageJsonPath, ".."), typedocPackageConfig?.readmeFile),
|
|
280
278
|
program,
|
|
281
279
|
sourceFile,
|
|
282
280
|
});
|
|
283
281
|
}
|
|
284
282
|
return results;
|
|
285
283
|
}
|
|
284
|
+
function discoverReadmeFile(logger, packageDir, userReadme) {
|
|
285
|
+
if (userReadme) {
|
|
286
|
+
if (!FS.existsSync(Path.join(packageDir, userReadme))) {
|
|
287
|
+
logger.warn(`Failed to find ${userReadme} in ${(0, paths_1.nicePath)(packageDir)}`);
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
return Path.resolve(Path.join(packageDir, userReadme));
|
|
291
|
+
}
|
|
292
|
+
for (const file of FS.readdirSync(packageDir)) {
|
|
293
|
+
if (file.toLowerCase() === "readme.md") {
|
|
294
|
+
return Path.resolve(Path.join(packageDir, file));
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
@@ -74,6 +74,7 @@ export interface TypeDocOptionMap {
|
|
|
74
74
|
excludeTags: `@${string}`[];
|
|
75
75
|
readme: string;
|
|
76
76
|
cname: string;
|
|
77
|
+
sourceLinkTemplate: string;
|
|
77
78
|
gitRevision: string;
|
|
78
79
|
gitRemote: string;
|
|
79
80
|
htmlLang: string;
|
|
@@ -82,6 +83,9 @@ export interface TypeDocOptionMap {
|
|
|
82
83
|
hideGenerator: boolean;
|
|
83
84
|
searchInComments: boolean;
|
|
84
85
|
cleanOutputDir: boolean;
|
|
86
|
+
titleLink: string;
|
|
87
|
+
navigationLinks: ManuallyValidatedOption<Record<string, string>>;
|
|
88
|
+
sidebarLinks: ManuallyValidatedOption<Record<string, string>>;
|
|
85
89
|
commentStyle: typeof CommentStyle;
|
|
86
90
|
blockTags: `@${string}`[];
|
|
87
91
|
inlineTags: `@${string}`[];
|
|
@@ -235,6 +235,10 @@ function addTypeDocOptions(options) {
|
|
|
235
235
|
name: "cname",
|
|
236
236
|
help: "Set the CNAME file text, it's useful for custom domains on GitHub Pages.",
|
|
237
237
|
});
|
|
238
|
+
options.addDeclaration({
|
|
239
|
+
name: "sourceLinkTemplate",
|
|
240
|
+
help: "Specify a link template to be used when generating source urls. If not set, will be automatically created using the git remote. Supports {path}, {line}, {gitRevision} placeholders.",
|
|
241
|
+
});
|
|
238
242
|
options.addDeclaration({
|
|
239
243
|
name: "gitRevision",
|
|
240
244
|
help: "Use specified revision instead of the last revision for linking to GitHub/Bitbucket source files.",
|
|
@@ -276,6 +280,39 @@ function addTypeDocOptions(options) {
|
|
|
276
280
|
type: declaration_1.ParameterType.Boolean,
|
|
277
281
|
defaultValue: true,
|
|
278
282
|
});
|
|
283
|
+
options.addDeclaration({
|
|
284
|
+
name: "titleLink",
|
|
285
|
+
help: "Set the link the title in the header points to. Defaults to the documentation homepage.",
|
|
286
|
+
type: declaration_1.ParameterType.String,
|
|
287
|
+
});
|
|
288
|
+
options.addDeclaration({
|
|
289
|
+
name: "navigationLinks",
|
|
290
|
+
help: "Defines links to be included in the header.",
|
|
291
|
+
type: declaration_1.ParameterType.Mixed,
|
|
292
|
+
defaultValue: {},
|
|
293
|
+
validate(value) {
|
|
294
|
+
if (!isObject(value)) {
|
|
295
|
+
throw new Error(`navigationLinks must be an object with string labels as keys and URL values.`);
|
|
296
|
+
}
|
|
297
|
+
if (Object.values(value).some((x) => typeof x !== "string")) {
|
|
298
|
+
throw new Error(`All values of navigationLinks must be string URLs.`);
|
|
299
|
+
}
|
|
300
|
+
},
|
|
301
|
+
});
|
|
302
|
+
options.addDeclaration({
|
|
303
|
+
name: "sidebarLinks",
|
|
304
|
+
help: "Defines links to be included in the sidebar.",
|
|
305
|
+
type: declaration_1.ParameterType.Mixed,
|
|
306
|
+
defaultValue: {},
|
|
307
|
+
validate(value) {
|
|
308
|
+
if (!isObject(value)) {
|
|
309
|
+
throw new Error(`sidebarLinks must be an object with string labels as keys and URL values.`);
|
|
310
|
+
}
|
|
311
|
+
if (Object.values(value).some((x) => typeof x !== "string")) {
|
|
312
|
+
throw new Error(`All values of sidebarLinks must be string URLs.`);
|
|
313
|
+
}
|
|
314
|
+
},
|
|
315
|
+
});
|
|
279
316
|
///////////////////////////
|
|
280
317
|
///// Comment Options /////
|
|
281
318
|
///////////////////////////
|
|
@@ -9,6 +9,7 @@ declare const typedocPackageManifestConfigSchema: {
|
|
|
9
9
|
displayName: import("./validation").Optional<StringConstructor>;
|
|
10
10
|
entryPoint: import("./validation").Optional<StringConstructor>;
|
|
11
11
|
readmeFile: import("./validation").Optional<StringConstructor>;
|
|
12
|
+
tsconfig: import("./validation").Optional<StringConstructor>;
|
|
12
13
|
[additionalProperties]: boolean;
|
|
13
14
|
};
|
|
14
15
|
export declare type TypedocPackageManifestConfig = Infer<typeof typedocPackageManifestConfigSchema>;
|
|
@@ -32,6 +32,7 @@ const typedocPackageManifestConfigSchema = {
|
|
|
32
32
|
displayName: (0, validation_1.optional)(String),
|
|
33
33
|
entryPoint: (0, validation_1.optional)(String),
|
|
34
34
|
readmeFile: (0, validation_1.optional)(String),
|
|
35
|
+
tsconfig: (0, validation_1.optional)(String),
|
|
35
36
|
[validation_1.additionalProperties]: false,
|
|
36
37
|
};
|
|
37
38
|
/**
|
package/package.json
CHANGED
package/static/style.css
CHANGED
|
@@ -825,6 +825,15 @@ input[type="checkbox"]:checked ~ svg .tsd-checkbox-checkmark {
|
|
|
825
825
|
padding-left: 5.5rem;
|
|
826
826
|
}
|
|
827
827
|
|
|
828
|
+
#tsd-sidebar-links a {
|
|
829
|
+
margin-top: 0;
|
|
830
|
+
margin-bottom: 0.5rem;
|
|
831
|
+
line-height: 1.25rem;
|
|
832
|
+
}
|
|
833
|
+
#tsd-sidebar-links a:last-of-type {
|
|
834
|
+
margin-bottom: 0;
|
|
835
|
+
}
|
|
836
|
+
|
|
828
837
|
a.tsd-index-link {
|
|
829
838
|
margin: 0.25rem 0;
|
|
830
839
|
font-size: 1rem;
|
|
@@ -978,7 +987,8 @@ a.tsd-index-link {
|
|
|
978
987
|
right: -40px;
|
|
979
988
|
}
|
|
980
989
|
#tsd-search .field input,
|
|
981
|
-
#tsd-search .title
|
|
990
|
+
#tsd-search .title,
|
|
991
|
+
#tsd-toolbar-links a {
|
|
982
992
|
transition: opacity 0.2s;
|
|
983
993
|
}
|
|
984
994
|
#tsd-search .results {
|
|
@@ -1022,7 +1032,8 @@ a.tsd-index-link {
|
|
|
1022
1032
|
top: 0;
|
|
1023
1033
|
opacity: 1;
|
|
1024
1034
|
}
|
|
1025
|
-
#tsd-search.has-focus .title
|
|
1035
|
+
#tsd-search.has-focus .title,
|
|
1036
|
+
#tsd-search.has-focus #tsd-toolbar-links a {
|
|
1026
1037
|
z-index: 0;
|
|
1027
1038
|
opacity: 0;
|
|
1028
1039
|
}
|
|
@@ -1036,6 +1047,22 @@ a.tsd-index-link {
|
|
|
1036
1047
|
display: block;
|
|
1037
1048
|
}
|
|
1038
1049
|
|
|
1050
|
+
#tsd-toolbar-links {
|
|
1051
|
+
position: absolute;
|
|
1052
|
+
top: 0;
|
|
1053
|
+
right: 2rem;
|
|
1054
|
+
height: 100%;
|
|
1055
|
+
display: flex;
|
|
1056
|
+
align-items: center;
|
|
1057
|
+
justify-content: flex-end;
|
|
1058
|
+
}
|
|
1059
|
+
#tsd-toolbar-links a {
|
|
1060
|
+
margin-left: 1.5rem;
|
|
1061
|
+
}
|
|
1062
|
+
#tsd-toolbar-links a:hover {
|
|
1063
|
+
text-decoration: underline;
|
|
1064
|
+
}
|
|
1065
|
+
|
|
1039
1066
|
.tsd-signature {
|
|
1040
1067
|
margin: 0 0 1rem 0;
|
|
1041
1068
|
padding: 1rem 0.5rem;
|
|
@@ -1134,6 +1161,11 @@ ul.tsd-type-parameter-list h5 {
|
|
|
1134
1161
|
.tsd-page-toolbar .table-cell:first-child {
|
|
1135
1162
|
width: 100%;
|
|
1136
1163
|
}
|
|
1164
|
+
.tsd-page-toolbar .tsd-toolbar-icon {
|
|
1165
|
+
box-sizing: border-box;
|
|
1166
|
+
line-height: 0;
|
|
1167
|
+
padding: 12px 0;
|
|
1168
|
+
}
|
|
1137
1169
|
|
|
1138
1170
|
.tsd-page-toolbar--hide {
|
|
1139
1171
|
transform: translateY(-100%);
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.RepositoryType = void 0;
|
|
4
|
-
var RepositoryType;
|
|
5
|
-
(function (RepositoryType) {
|
|
6
|
-
RepositoryType["GitHub"] = "github";
|
|
7
|
-
RepositoryType["Bitbucket"] = "bitbucket";
|
|
8
|
-
RepositoryType["GitLab"] = "gitlab";
|
|
9
|
-
})(RepositoryType = exports.RepositoryType || (exports.RepositoryType = {}));
|