typedoc 0.26.0-beta.3 → 0.26.0-beta.4
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/application.d.ts +6 -1
- package/dist/lib/application.js +5 -0
- package/dist/lib/cli.js +13 -0
- package/dist/lib/converter/comments/index.js +3 -0
- package/dist/lib/converter/plugins/ImplementsPlugin.js +3 -2
- package/dist/lib/converter/plugins/LinkResolverPlugin.js +7 -0
- package/dist/lib/converter/plugins/SourcePlugin.d.ts +1 -15
- package/dist/lib/converter/plugins/SourcePlugin.js +4 -45
- package/dist/lib/converter/utils/repository.d.ts +46 -1
- package/dist/lib/converter/utils/repository.js +191 -64
- package/dist/lib/internationalization/internationalization.d.ts +5 -2
- package/dist/lib/internationalization/internationalization.js +42 -0
- package/dist/lib/internationalization/locales/jp.cjs +308 -0
- package/dist/lib/internationalization/locales/jp.d.cts +307 -0
- package/dist/lib/internationalization/locales/zh.cjs +308 -0
- package/dist/lib/internationalization/locales/zh.d.cts +307 -0
- package/dist/lib/internationalization/translatable.d.ts +184 -167
- package/dist/lib/internationalization/translatable.js +182 -166
- package/dist/lib/models/comments/comment.d.ts +1 -0
- package/dist/lib/models/reflections/abstract.d.ts +12 -11
- package/dist/lib/models/reflections/abstract.js +46 -49
- package/dist/lib/output/plugins/IconsPlugin.js +21 -17
- package/dist/lib/output/renderer.d.ts +2 -2
- package/dist/lib/output/themes/default/DefaultTheme.js +1 -1
- package/dist/lib/output/themes/default/partials/comment.d.ts +1 -1
- package/dist/lib/output/themes/default/partials/comment.js +11 -7
- package/dist/lib/output/themes/default/partials/navigation.js +8 -2
- package/dist/lib/output/themes/default/templates/reflection.js +2 -2
- package/dist/lib/output/themes/lib.d.ts +0 -1
- package/dist/lib/output/themes/lib.js +0 -4
- package/dist/lib/utils/general.d.ts +1 -0
- package/dist/lib/utils/general.js +5 -0
- package/dist/lib/utils/options/sources/typedoc.js +1 -0
- package/dist/lib/utils/options/tsdoc-defaults.d.ts +1 -1
- package/dist/lib/utils/options/tsdoc-defaults.js +5 -1
- package/dist/lib/utils/paths.js +11 -1
- package/dist/lib/utils/perf.js +3 -1
- package/dist/lib/validation/links.d.ts +1 -1
- package/dist/lib/validation/links.js +42 -7
- package/package.json +2 -2
- package/static/main.js +1 -1
- package/static/style.css +6 -0
- package/dist/lib/converter/utils/base-path.d.ts +0 -36
- package/dist/lib/converter/utils/base-path.js +0 -117
- package/dist/lib/internationalization/locales/test.cjs +0 -8
- package/dist/lib/internationalization/locales/test.d.cts +0 -5
|
@@ -22,6 +22,11 @@ export declare function createAppForTesting(): Application;
|
|
|
22
22
|
*
|
|
23
23
|
* Both the {@link Converter} and the {@link Renderer} emit a series of events while processing the project.
|
|
24
24
|
* Subscribe to these Events to control the application flow or alter the output.
|
|
25
|
+
*
|
|
26
|
+
* @remarks
|
|
27
|
+
*
|
|
28
|
+
* Access to an Application instance can be retrieved with {@link Application.bootstrap} or
|
|
29
|
+
* {@link Application.bootstrapWithPlugins}. It can not be constructed manually.
|
|
25
30
|
*/
|
|
26
31
|
export declare class Application extends ChildableComponent<Application, AbstractComponent<Application>> {
|
|
27
32
|
/**
|
|
@@ -66,7 +71,7 @@ export declare class Application extends ChildableComponent<Application, Abstrac
|
|
|
66
71
|
/**
|
|
67
72
|
* The version number of TypeDoc.
|
|
68
73
|
*/
|
|
69
|
-
static VERSION: string;
|
|
74
|
+
static readonly VERSION: string;
|
|
70
75
|
/**
|
|
71
76
|
* Emitted after plugins have been loaded and options have been read, but before they have been frozen.
|
|
72
77
|
* The listener will be given an instance of {@link Application}.
|
package/dist/lib/application.js
CHANGED
|
@@ -130,6 +130,11 @@ const DEFAULT_READERS = [
|
|
|
130
130
|
*
|
|
131
131
|
* Both the {@link Converter} and the {@link Renderer} emit a series of events while processing the project.
|
|
132
132
|
* Subscribe to these Events to control the application flow or alter the output.
|
|
133
|
+
*
|
|
134
|
+
* @remarks
|
|
135
|
+
*
|
|
136
|
+
* Access to an Application instance can be retrieved with {@link Application.bootstrap} or
|
|
137
|
+
* {@link Application.bootstrapWithPlugins}. It can not be constructed manually.
|
|
133
138
|
*/
|
|
134
139
|
let Application = (() => {
|
|
135
140
|
var _Application_lang_accessor_storage, _Application_skipErrorChecking_accessor_storage, _Application_entryPointStrategy_accessor_storage, _Application_entryPoints_accessor_storage;
|
package/dist/lib/cli.js
CHANGED
|
@@ -49,6 +49,7 @@ async function main() {
|
|
|
49
49
|
const exitCode = await run(app);
|
|
50
50
|
if (exitCode !== ExitCodes.Watching) {
|
|
51
51
|
app.logger.verbose(`Full run took ${Date.now() - start}ms`);
|
|
52
|
+
logRunSummary(app.logger);
|
|
52
53
|
process.exit(exitCode);
|
|
53
54
|
}
|
|
54
55
|
}
|
|
@@ -131,3 +132,15 @@ async function run(app) {
|
|
|
131
132
|
}
|
|
132
133
|
return ExitCodes.Ok;
|
|
133
134
|
}
|
|
135
|
+
/**
|
|
136
|
+
* Generate a string with the number of errors and warnings found.
|
|
137
|
+
*/
|
|
138
|
+
function logRunSummary(logger) {
|
|
139
|
+
const { errorCount, warningCount } = logger;
|
|
140
|
+
if (errorCount) {
|
|
141
|
+
logger.error(logger.i18n.found_0_errors_and_1_warnings(errorCount.toString(), warningCount.toString()));
|
|
142
|
+
}
|
|
143
|
+
else if (warningCount) {
|
|
144
|
+
logger.warn(logger.i18n.found_0_errors_and_1_warnings(errorCount.toString(), warningCount.toString()));
|
|
145
|
+
}
|
|
146
|
+
}
|
|
@@ -58,6 +58,9 @@ function getCommentWithCache(discovered, config, logger, checker, files) {
|
|
|
58
58
|
}
|
|
59
59
|
function getCommentImpl(commentSource, config, logger, moduleComment, checker, files) {
|
|
60
60
|
const comment = getCommentWithCache(commentSource, config, logger, checker, files);
|
|
61
|
+
if (comment?.getTag("@import") || comment?.getTag("@license")) {
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
61
64
|
if (moduleComment && comment) {
|
|
62
65
|
// Module comment, make sure it is tagged with @packageDocumentation or @module.
|
|
63
66
|
// If it isn't then the comment applies to the first statement in the file, so throw it away.
|
|
@@ -292,7 +292,7 @@ function findProperty(reflection, parent) {
|
|
|
292
292
|
: prop.name === reflection.name;
|
|
293
293
|
});
|
|
294
294
|
}
|
|
295
|
-
function createLink(context, reflection, clause, expr, symbol,
|
|
295
|
+
function createLink(context, reflection, clause, expr, symbol, isInherit) {
|
|
296
296
|
const project = context.project;
|
|
297
297
|
const name = `${expr.expression.getText()}.${(0, utils_1.getHumanName)(symbol.name)}`;
|
|
298
298
|
link(reflection);
|
|
@@ -313,7 +313,8 @@ function createLink(context, reflection, clause, expr, symbol, isOverwrite) {
|
|
|
313
313
|
target.implementationOf ??= types_1.ReferenceType.createBrokenReference(name, project);
|
|
314
314
|
return;
|
|
315
315
|
}
|
|
316
|
-
if (
|
|
316
|
+
if (isInherit) {
|
|
317
|
+
target.setFlag(index_1.ReflectionFlag.Inherited);
|
|
317
318
|
target.inheritedFrom ??= types_1.ReferenceType.createBrokenReference(name, project);
|
|
318
319
|
}
|
|
319
320
|
else {
|
|
@@ -86,6 +86,13 @@ let LinkResolverPlugin = (() => {
|
|
|
86
86
|
if (reflection.comment) {
|
|
87
87
|
this.owner.resolveLinks(reflection.comment, reflection);
|
|
88
88
|
}
|
|
89
|
+
if (reflection.isDeclaration()) {
|
|
90
|
+
reflection.type?.visit((0, models_1.makeRecursiveVisitor)({
|
|
91
|
+
union: (type) => {
|
|
92
|
+
type.elementSummaries = type.elementSummaries?.map((parts) => this.owner.resolveLinks(parts, reflection));
|
|
93
|
+
},
|
|
94
|
+
}));
|
|
95
|
+
}
|
|
89
96
|
if (reflection instanceof models_1.DeclarationReflection &&
|
|
90
97
|
reflection.readme) {
|
|
91
98
|
reflection.readme = this.owner.resolveLinks(reflection.readme, reflection);
|
|
@@ -13,14 +13,7 @@ export declare class SourcePlugin extends ConverterComponent {
|
|
|
13
13
|
* All file names to find the base path from.
|
|
14
14
|
*/
|
|
15
15
|
private fileNames;
|
|
16
|
-
|
|
17
|
-
* List of known repositories.
|
|
18
|
-
*/
|
|
19
|
-
private repositories;
|
|
20
|
-
/**
|
|
21
|
-
* List of paths known to be not under git control.
|
|
22
|
-
*/
|
|
23
|
-
private ignoredPaths;
|
|
16
|
+
private repositories?;
|
|
24
17
|
/**
|
|
25
18
|
* Create a new SourceHandler instance.
|
|
26
19
|
*/
|
|
@@ -42,11 +35,4 @@ export declare class SourcePlugin extends ConverterComponent {
|
|
|
42
35
|
* @param context The context object describing the current state the converter is in.
|
|
43
36
|
*/
|
|
44
37
|
private onBeginResolve;
|
|
45
|
-
/**
|
|
46
|
-
* Check whether the given file is placed inside a repository.
|
|
47
|
-
*
|
|
48
|
-
* @param fileName The name of the file a repository should be looked for.
|
|
49
|
-
* @returns The found repository info or undefined.
|
|
50
|
-
*/
|
|
51
|
-
private getRepository;
|
|
52
38
|
}
|
|
@@ -62,7 +62,6 @@ const nodes_1 = require("../utils/nodes");
|
|
|
62
62
|
const path_1 = require("path");
|
|
63
63
|
const models_1 = require("../../models");
|
|
64
64
|
const repository_1 = require("../utils/repository");
|
|
65
|
-
const base_path_1 = require("../utils/base-path");
|
|
66
65
|
/**
|
|
67
66
|
* A handler that attaches source file information to reflections.
|
|
68
67
|
*/
|
|
@@ -104,14 +103,6 @@ let SourcePlugin = (() => {
|
|
|
104
103
|
* All file names to find the base path from.
|
|
105
104
|
*/
|
|
106
105
|
this.fileNames = (__runInitializers(this, _basePath_extraInitializers), new Set());
|
|
107
|
-
/**
|
|
108
|
-
* List of known repositories.
|
|
109
|
-
*/
|
|
110
|
-
this.repositories = {};
|
|
111
|
-
/**
|
|
112
|
-
* List of paths known to be not under git control.
|
|
113
|
-
*/
|
|
114
|
-
this.ignoredPaths = new Set();
|
|
115
106
|
}
|
|
116
107
|
get disableSources() { return __classPrivateFieldGet(this, _SourcePlugin_disableSources_accessor_storage, "f"); }
|
|
117
108
|
set disableSources(value) { __classPrivateFieldSet(this, _SourcePlugin_disableSources_accessor_storage, value, "f"); }
|
|
@@ -154,7 +145,7 @@ let SourcePlugin = (() => {
|
|
|
154
145
|
const symbol = reflection.project.getSymbolFromReflection(reflection);
|
|
155
146
|
for (const node of symbol?.declarations || []) {
|
|
156
147
|
const sourceFile = node.getSourceFile();
|
|
157
|
-
const fileName =
|
|
148
|
+
const fileName = (0, utils_1.normalizePath)(sourceFile.fileName);
|
|
158
149
|
this.fileNames.add(fileName);
|
|
159
150
|
let position;
|
|
160
151
|
if (typescript_1.default.isSourceFile(node)) {
|
|
@@ -171,7 +162,7 @@ let SourcePlugin = (() => {
|
|
|
171
162
|
if (this.disableSources || !sig)
|
|
172
163
|
return;
|
|
173
164
|
const sourceFile = sig.getSourceFile();
|
|
174
|
-
const fileName =
|
|
165
|
+
const fileName = (0, utils_1.normalizePath)(sourceFile.fileName);
|
|
175
166
|
this.fileNames.add(fileName);
|
|
176
167
|
const position = typescript_1.default.getLineAndCharacterOfPosition(sourceFile, getLocationNode(sig).getStart());
|
|
177
168
|
reflection.sources ||= [];
|
|
@@ -195,6 +186,7 @@ let SourcePlugin = (() => {
|
|
|
195
186
|
this.application.logger.warn(context.i18n.disable_git_set_and_git_revision_used());
|
|
196
187
|
}
|
|
197
188
|
const basePath = this.basePath || (0, utils_1.getCommonDirectory)([...this.fileNames]);
|
|
189
|
+
this.repositories ||= new repository_1.RepositoryManager(basePath, this.gitRevision, this.gitRemote, this.sourceLinkTemplate, this.disableGit, this.application.logger);
|
|
198
190
|
for (const id in context.project.reflections) {
|
|
199
191
|
const refl = context.project.reflections[id];
|
|
200
192
|
if (!(refl instanceof index_1.DeclarationReflection ||
|
|
@@ -206,46 +198,13 @@ let SourcePlugin = (() => {
|
|
|
206
198
|
}
|
|
207
199
|
for (const source of refl.sources || []) {
|
|
208
200
|
if (this.disableGit || (0, repository_1.gitIsInstalled)()) {
|
|
209
|
-
const repo = this.getRepository(
|
|
201
|
+
const repo = this.repositories.getRepository(source.fullFileName);
|
|
210
202
|
source.url = repo?.getURL(source.fullFileName, source.line);
|
|
211
203
|
}
|
|
212
204
|
source.fileName = (0, utils_1.normalizePath)((0, path_1.relative)(basePath, source.fullFileName));
|
|
213
205
|
}
|
|
214
206
|
}
|
|
215
207
|
}
|
|
216
|
-
/**
|
|
217
|
-
* Check whether the given file is placed inside a repository.
|
|
218
|
-
*
|
|
219
|
-
* @param fileName The name of the file a repository should be looked for.
|
|
220
|
-
* @returns The found repository info or undefined.
|
|
221
|
-
*/
|
|
222
|
-
getRepository(basePath, fileName) {
|
|
223
|
-
if (this.disableGit) {
|
|
224
|
-
return new repository_1.AssumedRepository(basePath, this.gitRevision, this.sourceLinkTemplate);
|
|
225
|
-
}
|
|
226
|
-
// Check for known non-repositories
|
|
227
|
-
const dirName = (0, path_1.dirname)(fileName);
|
|
228
|
-
const segments = dirName.split("/");
|
|
229
|
-
for (let i = segments.length; i > 0; i--) {
|
|
230
|
-
if (this.ignoredPaths.has(segments.slice(0, i).join("/"))) {
|
|
231
|
-
return;
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
// Check for known repositories
|
|
235
|
-
for (const path of Object.keys(this.repositories)) {
|
|
236
|
-
if (fileName.toLowerCase().startsWith(path)) {
|
|
237
|
-
return this.repositories[path];
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
// Try to create a new repository
|
|
241
|
-
const repository = repository_1.GitRepository.tryCreateRepository(dirName, this.sourceLinkTemplate, this.gitRevision, this.gitRemote, this.application.logger);
|
|
242
|
-
if (repository) {
|
|
243
|
-
this.repositories[repository.path.toLowerCase()] = repository;
|
|
244
|
-
return repository;
|
|
245
|
-
}
|
|
246
|
-
// No repository found, add path to ignored paths
|
|
247
|
-
this.ignoredPaths.add(dirName);
|
|
248
|
-
}
|
|
249
208
|
};
|
|
250
209
|
_SourcePlugin_disableSources_accessor_storage = new WeakMap();
|
|
251
210
|
_SourcePlugin_gitRevision_accessor_storage = new WeakMap();
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type Logger } from "../../utils";
|
|
2
2
|
export declare function gitIsInstalled(): boolean;
|
|
3
3
|
export interface Repository {
|
|
4
|
+
readonly path: string;
|
|
4
5
|
getURL(fileName: string, line: number): string | undefined;
|
|
5
6
|
}
|
|
6
7
|
export declare class AssumedRepository implements Repository {
|
|
@@ -48,4 +49,48 @@ export declare class GitRepository implements Repository {
|
|
|
48
49
|
*/
|
|
49
50
|
static tryCreateRepository(path: string, sourceLinkTemplate: string, gitRevision: string, gitRemote: string, logger: Logger): GitRepository | undefined;
|
|
50
51
|
}
|
|
52
|
+
/**
|
|
53
|
+
* Responsible for keeping track of 0-N repositories which exist on a machine.
|
|
54
|
+
* This used to be inlined in SourcePlugin, moved out for easy unit testing.
|
|
55
|
+
*
|
|
56
|
+
* Git repositories can be nested. Files should be resolved to a repo as shown
|
|
57
|
+
* below:
|
|
58
|
+
* ```text
|
|
59
|
+
* /project
|
|
60
|
+
* /project/.git (A)
|
|
61
|
+
* /project/file.js (A)
|
|
62
|
+
* /project/folder/file.js (A)
|
|
63
|
+
* /project/sub/.git (B)
|
|
64
|
+
* /project/sub/file.js (B)
|
|
65
|
+
* ```
|
|
66
|
+
*
|
|
67
|
+
* In order words, it is not safe to assume that just because a file is within
|
|
68
|
+
* the `/project` directory, that it belongs to repo `A`. As calling git is
|
|
69
|
+
* expensive (~20-300ms depending on the machine, antivirus, etc.) we check for
|
|
70
|
+
* `.git` folders manually, and only call git if one is found.
|
|
71
|
+
*
|
|
72
|
+
* Symlinked files have the potential to further complicate this. If TypeScript's
|
|
73
|
+
* `preserveSymlinks` option is on, then this may be passed the path to a symlinked
|
|
74
|
+
* file. Unlike TypeScript, we will resolve the path, as the repo link should really
|
|
75
|
+
* point to the actual file.
|
|
76
|
+
*/
|
|
77
|
+
export declare class RepositoryManager {
|
|
78
|
+
private basePath;
|
|
79
|
+
private gitRevision;
|
|
80
|
+
private gitRemote;
|
|
81
|
+
private sourceLinkTemplate;
|
|
82
|
+
private disableGit;
|
|
83
|
+
private logger;
|
|
84
|
+
private cache;
|
|
85
|
+
private assumedRepo;
|
|
86
|
+
constructor(basePath: string, gitRevision: string, gitRemote: string, sourceLinkTemplate: string, disableGit: boolean, logger: Logger);
|
|
87
|
+
/**
|
|
88
|
+
* Check whether the given file is placed inside a repository.
|
|
89
|
+
*
|
|
90
|
+
* @param fileName The name of the file a repository should be looked for.
|
|
91
|
+
* @returns The found repository info or undefined.
|
|
92
|
+
*/
|
|
93
|
+
getRepository(fileName: string): Repository | undefined;
|
|
94
|
+
private getRepositoryFolder;
|
|
95
|
+
}
|
|
51
96
|
export declare function guessSourceUrlTemplate(remotes: string[]): string | undefined;
|
|
@@ -1,10 +1,47 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
|
|
3
|
+
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
|
|
4
|
+
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
|
|
5
|
+
var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
|
|
6
|
+
var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
|
|
7
|
+
var _, done = false;
|
|
8
|
+
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
9
|
+
var context = {};
|
|
10
|
+
for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
|
|
11
|
+
for (var p in contextIn.access) context.access[p] = contextIn.access[p];
|
|
12
|
+
context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
|
|
13
|
+
var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
|
|
14
|
+
if (kind === "accessor") {
|
|
15
|
+
if (result === void 0) continue;
|
|
16
|
+
if (result === null || typeof result !== "object") throw new TypeError("Object expected");
|
|
17
|
+
if (_ = accept(result.get)) descriptor.get = _;
|
|
18
|
+
if (_ = accept(result.set)) descriptor.set = _;
|
|
19
|
+
if (_ = accept(result.init)) initializers.unshift(_);
|
|
20
|
+
}
|
|
21
|
+
else if (_ = accept(result)) {
|
|
22
|
+
if (kind === "field") initializers.unshift(_);
|
|
23
|
+
else descriptor[key] = _;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
|
27
|
+
done = true;
|
|
28
|
+
};
|
|
29
|
+
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
|
|
30
|
+
var useValue = arguments.length > 2;
|
|
31
|
+
for (var i = 0; i < initializers.length; i++) {
|
|
32
|
+
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
|
|
33
|
+
}
|
|
34
|
+
return useValue ? value : void 0;
|
|
35
|
+
};
|
|
2
36
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.GitRepository = exports.AssumedRepository = void 0;
|
|
37
|
+
exports.RepositoryManager = exports.GitRepository = exports.AssumedRepository = void 0;
|
|
4
38
|
exports.gitIsInstalled = gitIsInstalled;
|
|
5
39
|
exports.guessSourceUrlTemplate = guessSourceUrlTemplate;
|
|
6
40
|
const child_process_1 = require("child_process");
|
|
7
|
-
const
|
|
41
|
+
const utils_1 = require("../../utils");
|
|
42
|
+
const general_1 = require("../../utils/general");
|
|
43
|
+
const path_1 = require("path");
|
|
44
|
+
const fs_1 = require("fs");
|
|
8
45
|
const TEN_MEGABYTES = 1024 * 10000;
|
|
9
46
|
function git(...args) {
|
|
10
47
|
return (0, child_process_1.spawnSync)("git", args, {
|
|
@@ -38,82 +75,172 @@ exports.AssumedRepository = AssumedRepository;
|
|
|
38
75
|
/**
|
|
39
76
|
* Stores data of a repository.
|
|
40
77
|
*/
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
78
|
+
let GitRepository = (() => {
|
|
79
|
+
var _a;
|
|
80
|
+
let _files_decorators;
|
|
81
|
+
let _files_initializers = [];
|
|
82
|
+
let _files_extraInitializers = [];
|
|
83
|
+
return _a = class GitRepository {
|
|
84
|
+
/**
|
|
85
|
+
* Create a new Repository instance.
|
|
86
|
+
*
|
|
87
|
+
* @param path The root path of the repository.
|
|
88
|
+
*/
|
|
89
|
+
constructor(path, gitRevision, urlTemplate) {
|
|
90
|
+
/**
|
|
91
|
+
* All files tracked by the repository.
|
|
92
|
+
*/
|
|
93
|
+
this.files = __runInitializers(this, _files_initializers, new Set());
|
|
94
|
+
this.urlTemplate = __runInitializers(this, _files_extraInitializers);
|
|
95
|
+
this.path = path;
|
|
96
|
+
this.gitRevision = gitRevision;
|
|
97
|
+
this.urlTemplate = urlTemplate;
|
|
98
|
+
const out = git("-C", path, "ls-files", "-z");
|
|
99
|
+
if (out.status === 0) {
|
|
100
|
+
out.stdout.split("\0").forEach((file) => {
|
|
101
|
+
if (file !== "") {
|
|
102
|
+
this.files.add((0, utils_1.normalizePath)(path + "/" + file));
|
|
103
|
+
}
|
|
104
|
+
});
|
|
60
105
|
}
|
|
61
|
-
}
|
|
62
|
-
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Get the URL of the given file on GitHub or Bitbucket.
|
|
109
|
+
*
|
|
110
|
+
* @param fileName The file whose URL should be determined.
|
|
111
|
+
* @returns A URL pointing to the web preview of the given file or undefined.
|
|
112
|
+
*/
|
|
113
|
+
getURL(fileName, line) {
|
|
114
|
+
if (!this.files.has(fileName)) {
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
const replacements = {
|
|
118
|
+
gitRevision: this.gitRevision,
|
|
119
|
+
"gitRevision:short": this.gitRevision.substring(0, 8),
|
|
120
|
+
path: fileName.substring(this.path.length + 1),
|
|
121
|
+
line,
|
|
122
|
+
};
|
|
123
|
+
return this.urlTemplate.replace(/\{(gitRevision|gitRevision:short|path|line)\}/g, (_, key) => replacements[key]);
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Try to create a new repository instance.
|
|
127
|
+
*
|
|
128
|
+
* Checks whether the given path is the root of a valid repository and if so
|
|
129
|
+
* creates a new instance of {@link GitRepository}.
|
|
130
|
+
*
|
|
131
|
+
* @param path The potential repository root.
|
|
132
|
+
* @returns A new instance of {@link GitRepository} or undefined.
|
|
133
|
+
*/
|
|
134
|
+
static tryCreateRepository(path, sourceLinkTemplate, gitRevision, gitRemote, logger) {
|
|
135
|
+
gitRevision ||= git("-C", path, "rev-parse", "HEAD").stdout.trim();
|
|
136
|
+
if (!gitRevision)
|
|
137
|
+
return; // Will only happen in a repo with no commits.
|
|
138
|
+
let urlTemplate;
|
|
139
|
+
if (sourceLinkTemplate) {
|
|
140
|
+
urlTemplate = sourceLinkTemplate;
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
const remotesOut = git("-C", path, "remote", "get-url", gitRemote);
|
|
144
|
+
if (remotesOut.status === 0) {
|
|
145
|
+
urlTemplate = guessSourceUrlTemplate(remotesOut.stdout.split("\n"));
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
logger.warn(logger.i18n.git_remote_0_not_valid(gitRemote));
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
if (!urlTemplate)
|
|
152
|
+
return;
|
|
153
|
+
return new _a((0, utils_1.normalizePath)(path), gitRevision, urlTemplate);
|
|
154
|
+
}
|
|
155
|
+
},
|
|
156
|
+
(() => {
|
|
157
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
|
|
158
|
+
_files_decorators = [general_1.NonEnumerable];
|
|
159
|
+
__esDecorate(null, null, _files_decorators, { kind: "field", name: "files", static: false, private: false, access: { has: obj => "files" in obj, get: obj => obj.files, set: (obj, value) => { obj.files = value; } }, metadata: _metadata }, _files_initializers, _files_extraInitializers);
|
|
160
|
+
if (_metadata) Object.defineProperty(_a, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
161
|
+
})(),
|
|
162
|
+
_a;
|
|
163
|
+
})();
|
|
164
|
+
exports.GitRepository = GitRepository;
|
|
165
|
+
/**
|
|
166
|
+
* Responsible for keeping track of 0-N repositories which exist on a machine.
|
|
167
|
+
* This used to be inlined in SourcePlugin, moved out for easy unit testing.
|
|
168
|
+
*
|
|
169
|
+
* Git repositories can be nested. Files should be resolved to a repo as shown
|
|
170
|
+
* below:
|
|
171
|
+
* ```text
|
|
172
|
+
* /project
|
|
173
|
+
* /project/.git (A)
|
|
174
|
+
* /project/file.js (A)
|
|
175
|
+
* /project/folder/file.js (A)
|
|
176
|
+
* /project/sub/.git (B)
|
|
177
|
+
* /project/sub/file.js (B)
|
|
178
|
+
* ```
|
|
179
|
+
*
|
|
180
|
+
* In order words, it is not safe to assume that just because a file is within
|
|
181
|
+
* the `/project` directory, that it belongs to repo `A`. As calling git is
|
|
182
|
+
* expensive (~20-300ms depending on the machine, antivirus, etc.) we check for
|
|
183
|
+
* `.git` folders manually, and only call git if one is found.
|
|
184
|
+
*
|
|
185
|
+
* Symlinked files have the potential to further complicate this. If TypeScript's
|
|
186
|
+
* `preserveSymlinks` option is on, then this may be passed the path to a symlinked
|
|
187
|
+
* file. Unlike TypeScript, we will resolve the path, as the repo link should really
|
|
188
|
+
* point to the actual file.
|
|
189
|
+
*/
|
|
190
|
+
class RepositoryManager {
|
|
191
|
+
constructor(basePath, gitRevision, gitRemote, sourceLinkTemplate, disableGit, logger) {
|
|
192
|
+
this.basePath = basePath;
|
|
193
|
+
this.gitRevision = gitRevision;
|
|
194
|
+
this.gitRemote = gitRemote;
|
|
195
|
+
this.sourceLinkTemplate = sourceLinkTemplate;
|
|
196
|
+
this.disableGit = disableGit;
|
|
197
|
+
this.logger = logger;
|
|
198
|
+
this.cache = new Map();
|
|
199
|
+
this.assumedRepo = new AssumedRepository(this.basePath, this.gitRevision, this.sourceLinkTemplate);
|
|
63
200
|
}
|
|
64
201
|
/**
|
|
65
|
-
*
|
|
202
|
+
* Check whether the given file is placed inside a repository.
|
|
66
203
|
*
|
|
67
|
-
* @param fileName The file
|
|
68
|
-
* @returns
|
|
204
|
+
* @param fileName The name of the file a repository should be looked for.
|
|
205
|
+
* @returns The found repository info or undefined.
|
|
69
206
|
*/
|
|
70
|
-
|
|
71
|
-
if (
|
|
72
|
-
return;
|
|
207
|
+
getRepository(fileName) {
|
|
208
|
+
if (this.disableGit) {
|
|
209
|
+
return this.assumedRepo;
|
|
73
210
|
}
|
|
74
|
-
|
|
75
|
-
gitRevision: this.gitRevision,
|
|
76
|
-
"gitRevision:short": this.gitRevision.substring(0, 8),
|
|
77
|
-
path: fileName.substring(this.path.length + 1),
|
|
78
|
-
line,
|
|
79
|
-
};
|
|
80
|
-
return this.urlTemplate.replace(/\{(gitRevision|gitRevision:short|path|line)\}/g, (_, key) => replacements[key]);
|
|
211
|
+
return this.getRepositoryFolder((0, utils_1.normalizePath)((0, path_1.dirname)(fileName)));
|
|
81
212
|
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
* Checks whether the given path is the root of a valid repository and if so
|
|
86
|
-
* creates a new instance of {@link GitRepository}.
|
|
87
|
-
*
|
|
88
|
-
* @param path The potential repository root.
|
|
89
|
-
* @returns A new instance of {@link GitRepository} or undefined.
|
|
90
|
-
*/
|
|
91
|
-
static tryCreateRepository(path, sourceLinkTemplate, gitRevision, gitRemote, logger) {
|
|
92
|
-
const topLevel = git("-C", path, "rev-parse", "--show-toplevel");
|
|
93
|
-
if (topLevel.status !== 0)
|
|
94
|
-
return;
|
|
95
|
-
gitRevision ||= git("-C", path, "rev-parse", "HEAD").stdout.trim();
|
|
96
|
-
if (!gitRevision)
|
|
97
|
-
return; // Will only happen in a repo with no commits.
|
|
98
|
-
let urlTemplate;
|
|
99
|
-
if (sourceLinkTemplate) {
|
|
100
|
-
urlTemplate = sourceLinkTemplate;
|
|
213
|
+
getRepositoryFolder(dir) {
|
|
214
|
+
if (this.cache.has(dir)) {
|
|
215
|
+
return this.cache.get(dir);
|
|
101
216
|
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
217
|
+
if ((0, fs_1.existsSync)((0, path_1.join)(dir, ".git"))) {
|
|
218
|
+
// This might just be a git repo, or we might be in some self-recursive symlink
|
|
219
|
+
// loop, and the repo is actually somewhere else. Ask Git where the repo actually is.
|
|
220
|
+
const repo = git("-C", dir, "rev-parse", "--show-toplevel");
|
|
221
|
+
if (repo.status === 0) {
|
|
222
|
+
const repoDir = repo.stdout.replace("\n", "");
|
|
223
|
+
// This check is only necessary if we're in a symlink loop, otherwise
|
|
224
|
+
// it will always be true.
|
|
225
|
+
if (!this.cache.has(repoDir)) {
|
|
226
|
+
this.cache.set(repoDir, GitRepository.tryCreateRepository(repoDir, this.sourceLinkTemplate, this.gitRevision, this.gitRemote, this.logger));
|
|
227
|
+
}
|
|
228
|
+
this.cache.set(dir, this.cache.get(repoDir));
|
|
106
229
|
}
|
|
107
230
|
else {
|
|
108
|
-
|
|
231
|
+
// Not a git repo, probably corrupt.
|
|
232
|
+
this.cache.set(dir, undefined);
|
|
109
233
|
}
|
|
110
234
|
}
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
235
|
+
else {
|
|
236
|
+
// We may be at the root of the file system, in which case there is no repo.
|
|
237
|
+
this.cache.set(dir, undefined);
|
|
238
|
+
this.cache.set(dir, this.getRepositoryFolder((0, path_1.dirname)(dir)));
|
|
239
|
+
}
|
|
240
|
+
return this.cache.get(dir);
|
|
114
241
|
}
|
|
115
242
|
}
|
|
116
|
-
exports.
|
|
243
|
+
exports.RepositoryManager = RepositoryManager;
|
|
117
244
|
// Should have three capturing groups:
|
|
118
245
|
// 1. hostname
|
|
119
246
|
// 2. user
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { Application } from "../application";
|
|
2
|
-
import { type BuiltinTranslatableStringArgs } from "./translatable";
|
|
2
|
+
import { translatable, type BuiltinTranslatableStringArgs } from "./translatable";
|
|
3
3
|
import { ReflectionKind } from "../models/reflections/kind";
|
|
4
|
+
import { ReflectionFlag } from "../models";
|
|
4
5
|
/**
|
|
5
6
|
* ### What is translatable?
|
|
6
7
|
* TypeDoc includes a lot of literal strings. By convention, messages which are displayed
|
|
@@ -73,9 +74,11 @@ export declare class Internationalization {
|
|
|
73
74
|
* Get the translation of the specified key, replacing placeholders
|
|
74
75
|
* with the arguments specified.
|
|
75
76
|
*/
|
|
76
|
-
translate<T extends keyof
|
|
77
|
+
translate<T extends keyof typeof translatable>(key: T, ...args: TranslatableStrings[T]): TranslatedString;
|
|
77
78
|
kindSingularString(kind: ReflectionKind): TranslatedString;
|
|
78
79
|
kindPluralString(kind: ReflectionKind): TranslatedString;
|
|
80
|
+
flagString(flag: ReflectionFlag): TranslatedString;
|
|
81
|
+
translateTagName(tag: `@${string}`): TranslatedString;
|
|
79
82
|
/**
|
|
80
83
|
* Add translations for a string which will be displayed to the user.
|
|
81
84
|
*/
|
|
@@ -7,6 +7,7 @@ const translatable_1 = require("./translatable");
|
|
|
7
7
|
const fs_1 = require("fs");
|
|
8
8
|
const path_1 = require("path");
|
|
9
9
|
const kind_1 = require("../models/reflections/kind");
|
|
10
|
+
const models_1 = require("../models");
|
|
10
11
|
// If we're running in ts-node, then we need the TS source rather than
|
|
11
12
|
// the compiled file.
|
|
12
13
|
const ext = process[Symbol.for("ts-node.register.instance")]
|
|
@@ -163,6 +164,47 @@ class Internationalization {
|
|
|
163
164
|
return this.proxy.kind_plural_document();
|
|
164
165
|
}
|
|
165
166
|
}
|
|
167
|
+
flagString(flag) {
|
|
168
|
+
switch (flag) {
|
|
169
|
+
case models_1.ReflectionFlag.None:
|
|
170
|
+
throw new Error("Should be unreachable");
|
|
171
|
+
case models_1.ReflectionFlag.Private:
|
|
172
|
+
return this.proxy.flag_private();
|
|
173
|
+
case models_1.ReflectionFlag.Protected:
|
|
174
|
+
return this.proxy.flag_protected();
|
|
175
|
+
case models_1.ReflectionFlag.Public:
|
|
176
|
+
return this.proxy.flag_public();
|
|
177
|
+
case models_1.ReflectionFlag.Static:
|
|
178
|
+
return this.proxy.flag_static();
|
|
179
|
+
case models_1.ReflectionFlag.External:
|
|
180
|
+
return this.proxy.flag_external();
|
|
181
|
+
case models_1.ReflectionFlag.Optional:
|
|
182
|
+
return this.proxy.flag_optional();
|
|
183
|
+
case models_1.ReflectionFlag.Rest:
|
|
184
|
+
return this.proxy.flag_rest();
|
|
185
|
+
case models_1.ReflectionFlag.Abstract:
|
|
186
|
+
return this.proxy.flag_abstract();
|
|
187
|
+
case models_1.ReflectionFlag.Const:
|
|
188
|
+
return this.proxy.flag_const();
|
|
189
|
+
case models_1.ReflectionFlag.Readonly:
|
|
190
|
+
return this.proxy.flag_readonly();
|
|
191
|
+
case models_1.ReflectionFlag.Inherited:
|
|
192
|
+
return this.proxy.flag_inherited();
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
translateTagName(tag) {
|
|
196
|
+
const tagName = tag.substring(1);
|
|
197
|
+
const translations = this.allTranslations.get(this.application?.lang ?? "en");
|
|
198
|
+
if (translations.has(`tag_${tagName}`)) {
|
|
199
|
+
return translations.get(`tag_${tagName}`);
|
|
200
|
+
}
|
|
201
|
+
// In English, the tag names are the translated names, once turned
|
|
202
|
+
// into title case.
|
|
203
|
+
return (tagName.substring(0, 1).toUpperCase() +
|
|
204
|
+
tagName
|
|
205
|
+
.substring(1)
|
|
206
|
+
.replace(/[a-z][A-Z]/g, (x) => `${x[0]} ${x[1]}`));
|
|
207
|
+
}
|
|
166
208
|
/**
|
|
167
209
|
* Add translations for a string which will be displayed to the user.
|
|
168
210
|
*/
|