typedoc-toolbox 0.0.1

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/LICENSE ADDED
@@ -0,0 +1,7 @@
1
+ Copyright 2025 - Present Hervé Perchec
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,64 @@
1
+ # typedoc-toolbox
2
+
3
+ [![author](https://img.shields.io/static/v1?label=\&message=Author:\&color=black)](http://herve-perchec.com/)
4
+ [![herve-perchec](http://herve-perchec.com/badge.svg)](http://herve-perchec.com/)
5
+ [![release](https://img.shields.io/gitlab/v/release/hperchec/typedoc-toolbox?include_prereleases\&logo=gitlab\&sort=semver)](https://gitlab.com/hperchec/typedoc-toolbox/-/releases)
6
+ [![pipeline-status](https://gitlab.com/hperchec/typedoc-toolbox/badges/v0.0.1/pipeline.svg)](https://gitlab.com/hperchec/typedoc-toolbox/commits/v0.0.1)
7
+ ![coverage](https://gitlab.com/hperchec/typedoc-toolbox/badges/v0.0.1/coverage.svg)
8
+ [![package](https://img.shields.io/npm/v/typedoc-toolbox?logo=npm)](https://www.npmjs.com/package/typedoc-toolbox)
9
+ [![downloads](https://img.shields.io/npm/dw/typedoc-toolbox?logo=npm)](https://www.npmjs.com/package/typedoc-toolbox)
10
+ [![issues](https://img.shields.io/gitlab/issues/open/hperchec/typedoc-toolbox?gitlab_url=https%3A%2F%2Fgitlab.com)](https://gitlab.com/hperchec/typedoc-toolbox/issues)
11
+ [![license](https://img.shields.io/gitlab/license/hperchec/typedoc-toolbox?gitlab_url=https%3A%2F%2Fgitlab.com)](https://gitlab.com/hperchec/typedoc-toolbox/-/blob/dd0823badca2649c726e982b074fb76665fbb1d6/LICENSE)
12
+
13
+ ## Table of contents
14
+
15
+ * [🍵 Introduction](#-introduction)
16
+ * [🚀 Get started](#-get-started)
17
+ * [🛠️ Usage](#️-usage)
18
+ * [🤝 Contribute](#-contribute)
19
+ * [👑 Author](#-author)
20
+ * [⚖️ License](#️-license)
21
+ * [📰 Changelog](#-changelog)
22
+
23
+ ## 🍵 Introduction
24
+
25
+ This library is a collection of useful tools for [TypeDoc](https://typedoc.org/index.html).
26
+
27
+ ## 🚀 Get started
28
+
29
+ This package is published on [NPM](https://www.npmjs.com/package/typedoc-toolbox).
30
+
31
+ ```sh
32
+ npm install typedoc-toolbox
33
+ ```
34
+
35
+ ## 🛠️ Usage
36
+
37
+ > 💡 Please check the [API documentation](https://gitlab.com/hperchec/typedoc-toolbox/-/blob/dd0823badca2649c726e982b074fb76665fbb1d6/docs/api/gen/README.md).
38
+
39
+ ## 🤝 Contribute
40
+
41
+ You would like to contribute to this project? You are welcome!
42
+
43
+ First, please check:
44
+
45
+ * the [contribution guide](https://gitlab.com/hperchec/typedoc-toolbox/-/blob/dd0823badca2649c726e982b074fb76665fbb1d6/CONTRIBUTING.md)
46
+ * the [code of conduct](https://gitlab.com/hperchec/typedoc-toolbox/-/blob/dd0823badca2649c726e982b074fb76665fbb1d6/CODE_OF_CONDUCT.md)
47
+
48
+ ## 👑 Author
49
+
50
+ Made with ❤ by [Hervé Perchec](https://gitlab.com/herveperchec)
51
+
52
+ ## ⚖️ License
53
+
54
+ [MIT](https://gitlab.com/hperchec/typedoc-toolbox/-/blob/dd0823badca2649c726e982b074fb76665fbb1d6/LICENSE)
55
+
56
+ ## 📰 Changelog
57
+
58
+ See all changes to this project in the [CHANGELOG.md](https://gitlab.com/hperchec/typedoc-toolbox/-/blob/dd0823badca2649c726e982b074fb76665fbb1d6/CHANGELOG.md) file.
59
+
60
+ ***
61
+
62
+ <!-- markdownlint-disable-next-line line-length -->
63
+
64
+ *README.md - this file was auto generated with [juisy](https://www.npmjs.com/package/juisy) README templater. Don't edit it.*
package/dist/index.cjs ADDED
@@ -0,0 +1,225 @@
1
+ /*!
2
+ * typedoc-toolbox v0.0.1
3
+ * MIT License
4
+ * Copyright © 2025-Present Hervé Perchec (https://gitlab.com/herveperchec)
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
10
+
11
+ const os = require('node:os');
12
+ const fs = require('node:fs/promises');
13
+ const node_fs = require('node:fs');
14
+ const path = require('node:path');
15
+ const juisy = require('juisy');
16
+ const dayjs = require('dayjs');
17
+ const td = require('typedoc');
18
+
19
+ function _interopNamespaceDefault(e) {
20
+ const n = Object.create(null, { [Symbol.toStringTag]: { value: 'Module' } });
21
+ if (e) {
22
+ for (const k in e) {
23
+ if (k !== 'default') {
24
+ const d = Object.getOwnPropertyDescriptor(e, k);
25
+ Object.defineProperty(n, k, d.get ? d : {
26
+ enumerable: true,
27
+ get: () => e[k]
28
+ });
29
+ }
30
+ }
31
+ }
32
+ n.default = e;
33
+ return Object.freeze(n);
34
+ }
35
+
36
+ const td__namespace = /*#__PURE__*/_interopNamespaceDefault(td);
37
+
38
+ class TDOptionError extends Error {
39
+ }
40
+ class TDCompileError extends Error {
41
+ }
42
+ class TDValidationError extends Error {
43
+ }
44
+ class TDOutputError extends Error {
45
+ }
46
+ const dryRunsTempRootDir = path.join(os.tmpdir(), "typedoc-toolbox-dry-runs");
47
+ async function createApp(options = {}, readers = []) {
48
+ return await td__namespace.Application.bootstrapWithPlugins({
49
+ // By default, only errors are logged
50
+ logLevel: 3,
51
+ // No entry points
52
+ entryPoints: [],
53
+ // Prevent cleaning output directory
54
+ cleanOutputDir: false,
55
+ ...options
56
+ }, [
57
+ // new td.TypeDocReader(),
58
+ // new td.PackageJsonReader(),
59
+ // new td.TSConfigReader()
60
+ ...readers
61
+ ]);
62
+ }
63
+ function getRawConfig(app) {
64
+ return app.options.getRawValues();
65
+ }
66
+ async function run(app, options) {
67
+ options = options ?? { dry: false };
68
+ if (options.dry) {
69
+ app.logger.info("Dry run started");
70
+ }
71
+ const optionsSnapshot = app.options.snapshot();
72
+ let context;
73
+ const start = Date.now();
74
+ const throwRunError = (error) => {
75
+ logRunSummary(app.logger);
76
+ throw error;
77
+ };
78
+ if (app.logger.hasErrors()) {
79
+ throwRunError(new TDOptionError("TypeDoc option error"));
80
+ }
81
+ if (app.options.getValue("treatWarningsAsErrors") && app.logger.hasWarnings()) {
82
+ throwRunError(new TDOptionError("TypeDoc option error"));
83
+ }
84
+ const getConverterContext = (ctx) => {
85
+ context = ctx;
86
+ };
87
+ app.converter.on(td__namespace.Converter.EVENT_END, getConverterContext);
88
+ if (!await app.convert() || app.logger.hasErrors()) {
89
+ throwRunError(new TDCompileError("Compilation error"));
90
+ }
91
+ if (app.options.getValue("treatWarningsAsErrors") && app.logger.hasWarnings()) {
92
+ throwRunError(new TDCompileError("Compilation error"));
93
+ }
94
+ app.converter.off(td__namespace.Converter.EVENT_END, getConverterContext);
95
+ const project = context.project;
96
+ const preValidationWarnCount = app.logger.warningCount;
97
+ app.validate(project);
98
+ const hadValidationWarnings = app.logger.warningCount !== preValidationWarnCount || app.logger.validationWarningCount != 0;
99
+ if (app.logger.hasErrors()) {
100
+ throwRunError(new TDValidationError("Validation error"));
101
+ }
102
+ if (hadValidationWarnings && (app.options.getValue("treatWarningsAsErrors") || app.options.getValue("treatValidationWarningsAsErrors"))) {
103
+ throwRunError(new TDValidationError("Validation error"));
104
+ }
105
+ if (app.options.getValue("emit") !== "none") {
106
+ if (options.dry) {
107
+ await dryOutput(app, project);
108
+ } else {
109
+ await app.generateOutputs(project);
110
+ }
111
+ if (app.logger.hasErrors()) {
112
+ throwRunError(new TDOutputError("Output error"));
113
+ }
114
+ if (app.options.getValue("treatWarningsAsErrors") && app.logger.hasWarnings()) {
115
+ throwRunError(new TDOutputError("Output error"));
116
+ }
117
+ }
118
+ app.options.restore(optionsSnapshot);
119
+ app.logger.verbose(`Full run took ${Date.now() - start}ms`);
120
+ return {
121
+ application: app,
122
+ context
123
+ };
124
+ }
125
+ async function dryOutput(app, project) {
126
+ const optionsSnapshot = app.options.snapshot();
127
+ app.options.setValue("cleanOutputDir", false);
128
+ if (!node_fs.existsSync(dryRunsTempRootDir)) {
129
+ await fs.mkdir(dryRunsTempRootDir);
130
+ }
131
+ const tempDirPath = path.join(dryRunsTempRootDir, dayjs().format("YYYYMMDDHHmmssSSS"));
132
+ await fs.mkdir(tempDirPath);
133
+ try {
134
+ app.logger.info(`Temporary folder "${tempDirPath}" succesfully created`);
135
+ const originalGetOutputSpecs = app.outputs.getOutputSpecs.bind(app.outputs);
136
+ app.outputs.getOutputSpecs = function() {
137
+ return originalGetOutputSpecs().map((outputSpec, index) => {
138
+ const extension = path.extname(outputSpec.path);
139
+ outputSpec.path = juisy.utils.path.toPosix(path.join(tempDirPath, `${outputSpec.name}_${index}${extension}`));
140
+ return outputSpec;
141
+ });
142
+ };
143
+ await app.generateOutputs(project);
144
+ app.logger.info(`Temporary folder "${tempDirPath}" succesfully deleted`);
145
+ app.outputs.getOutputSpecs = originalGetOutputSpecs;
146
+ app.options.restore(optionsSnapshot);
147
+ } finally {
148
+ await fs.rm(tempDirPath, { recursive: true, force: true });
149
+ }
150
+ }
151
+ function logRunSummary(logger) {
152
+ const { errorCount, warningCount } = logger;
153
+ if (errorCount) {
154
+ logger.error(
155
+ td__namespace.i18n.found_0_errors_and_1_warnings(
156
+ errorCount.toString(),
157
+ warningCount.toString()
158
+ )
159
+ );
160
+ } else if (warningCount) {
161
+ logger.warn(
162
+ td__namespace.i18n.found_0_errors_and_1_warnings(
163
+ errorCount.toString(),
164
+ warningCount.toString()
165
+ )
166
+ );
167
+ }
168
+ }
169
+ async function createReflectionUrlResolver(app) {
170
+ const outputSpecs = app.outputs.getOutputSpecs();
171
+ if (outputSpecs.length > 1) {
172
+ throw new Error(`Unable to create reflection URL resolver with multiple outputs [ ${outputSpecs.map((o) => `"${o.name}"`).join(", ")} ]. Please provide only one theme.`);
173
+ } else if (outputSpecs[0].name === "json") {
174
+ throw new Error(`Unable to create reflection URL resolver with JSON output.`);
175
+ }
176
+ const reflectionsCache = {};
177
+ const optionsSnapshot = app.options.snapshot();
178
+ app.options.setValue("emit", "docs");
179
+ let router;
180
+ let getFullUrl;
181
+ app.renderer.on(td__namespace.RendererEvent.BEGIN, () => {
182
+ router = app.renderer.router;
183
+ getFullUrl = router.getFullUrl.bind(router);
184
+ });
185
+ const { context } = await run(app, { dry: true });
186
+ app.options.restore(optionsSnapshot);
187
+ return function resolver(identifier) {
188
+ if (!reflectionsCache[identifier]) {
189
+ const tempRefl = new td__namespace.DeclarationReflection("__TEMP__", td__namespace.ReflectionKind.All, context.project);
190
+ tempRefl.comment = new td__namespace.Comment([
191
+ { kind: "inline-tag", tag: "@link", text: identifier }
192
+ ]);
193
+ app.converter.resolveLinks(tempRefl);
194
+ const resolvedTag = tempRefl.comment.summary[0];
195
+ const targetReflection = resolvedTag.target;
196
+ reflectionsCache[resolvedTag.text] = {
197
+ reflection: targetReflection,
198
+ url: targetReflection ? getFullUrl(targetReflection) : void 0
199
+ };
200
+ }
201
+ return reflectionsCache[identifier].url;
202
+ };
203
+ }
204
+ function getReflectionTag(tag, reflection) {
205
+ const comment = reflection.comment;
206
+ if (!comment) return;
207
+ return comment.getTag(tag);
208
+ }
209
+ function getReflectionTags(tag, reflection) {
210
+ const comment = reflection.comment;
211
+ if (!comment) return [];
212
+ return comment.getTags(tag);
213
+ }
214
+
215
+ exports.TDCompileError = TDCompileError;
216
+ exports.TDOptionError = TDOptionError;
217
+ exports.TDOutputError = TDOutputError;
218
+ exports.TDValidationError = TDValidationError;
219
+ exports.createApp = createApp;
220
+ exports.createReflectionUrlResolver = createReflectionUrlResolver;
221
+ exports.dryRunsTempRootDir = dryRunsTempRootDir;
222
+ exports.getRawConfig = getRawConfig;
223
+ exports.getReflectionTag = getReflectionTag;
224
+ exports.getReflectionTags = getReflectionTags;
225
+ exports.run = run;
@@ -0,0 +1,132 @@
1
+ /**
2
+ * @module
3
+ * @importTarget .
4
+ */
5
+ import * as td from 'typedoc';
6
+ /**
7
+ * All TypeDoc error types
8
+ */
9
+ export type TDError = TDOptionError | TDCompileError | TDValidationError | TDOutputError;
10
+ /**
11
+ * TypeDoc option error
12
+ */
13
+ export declare class TDOptionError extends Error {
14
+ }
15
+ /**
16
+ * TypeDoc compilation error
17
+ */
18
+ export declare class TDCompileError extends Error {
19
+ }
20
+ /**
21
+ * TypeDoc validation error
22
+ */
23
+ export declare class TDValidationError extends Error {
24
+ }
25
+ /**
26
+ * TypeDoc output error
27
+ */
28
+ export declare class TDOutputError extends Error {
29
+ }
30
+ /**
31
+ * {@link createApp} function options
32
+ */
33
+ export interface CreateAppOptions extends Omit<td.Configuration.TypeDocOptions, 'help' | 'version' | 'watch' | 'plugin'> {
34
+ plugin?: Array<string | ((app: td.Application) => Promise<void> | void)>;
35
+ }
36
+ /**
37
+ * {@link run} function options
38
+ */
39
+ export interface RunOptions {
40
+ /**
41
+ * Dry run (no emit). Default: `false`
42
+ */
43
+ dry: boolean;
44
+ }
45
+ /**
46
+ * Type of function returned by {@link createReflectionUrlResolver}.
47
+ * @param identifier - The reflection identifier in a `@link` style
48
+ * @returns The resolved URL or undefined
49
+ */
50
+ export type ReflectionUrlResolver = (identifier: string) => string | undefined;
51
+ /**
52
+ * The path of temporary folder for dry runs
53
+ */
54
+ export declare const dryRunsTempRootDir: string;
55
+ /**
56
+ * Create and boot a new TypeDoc application
57
+ *
58
+ * Default options:
59
+ * - **logLevel**: `3`
60
+ * - **entryPoints**: `[]`
61
+ * - **cleanOutputDir**: `false`
62
+ *
63
+ * @param options - The base options
64
+ * @param readers - The option readers
65
+ * @returns The created application
66
+ *
67
+ * @example
68
+ * import * as td from 'typedoc'
69
+ *
70
+ * const app = await createApp()
71
+ * // With options
72
+ * const app = await createApp({
73
+ * // See CreateAppOptions
74
+ * })
75
+ * // With default readers
76
+ * const app = await createApp({}, [
77
+ * new td.TypeDocReader(),
78
+ * new td.PackageJsonReader(),
79
+ * new td.TSConfigReader()
80
+ * ])
81
+ */
82
+ export declare function createApp(options?: CreateAppOptions, readers?: td.Configuration.OptionsReader[]): Promise<td.Application>;
83
+ /**
84
+ * Get all of the TypeDoc option values defined in the app option container.
85
+ * @param app - The TypeDoc Application instance
86
+ */
87
+ export declare function getRawConfig(app: td.Application): Readonly<Partial<td.Configuration.TypeDocOptionValues>>;
88
+ /**
89
+ * Run a TypeDoc process like the CLI does.
90
+ *
91
+ * This code is widely inspired from
92
+ * [TypeDoc library sources](https://github.com/TypeStrong/typedoc/blob/v0.28.16/src/lib/cli.ts)
93
+ *
94
+ * Thanks to [Gerrit Birkeland](https://github.com/Gerrit0), the author of TypeDoc.
95
+ *
96
+ * @param app - The TypeDoc Application instance
97
+ *
98
+ * @example
99
+ * const result = await run(app)
100
+ * // Dry run
101
+ * const result = await run(app, { dry: true })
102
+ */
103
+ export declare function run(app: td.Application, options?: RunOptions): Promise<{
104
+ application: td.Application;
105
+ context: td.Context;
106
+ }>;
107
+ /**
108
+ * Create a reflection URL resolver from the given TypeDoc application instance.
109
+ * @returns The resolver function
110
+ * @example
111
+ * // With the default "html" output
112
+ * const resolver = await createReflectionUrlResolver(app)
113
+ * // For a "bar" constant in the "foo" module
114
+ * resolver('foo!bar') // => 'variables/foo.bar.html'
115
+ * // For a "bar" method of the "Foo" class in the "foo" module
116
+ * resolver('foo!Foo#bar') // => 'classes/foo.Foo.html#bar'
117
+ */
118
+ export declare function createReflectionUrlResolver(app: td.Application): Promise<ReflectionUrlResolver>;
119
+ /**
120
+ * Get the tag in reflection comment
121
+ * @param tag - The tag to find
122
+ * @param reflection - The reflection object
123
+ * @returns The found comment tag or undefined
124
+ */
125
+ export declare function getReflectionTag(tag: td.TagString, reflection: td.Reflection): td.CommentTag | undefined;
126
+ /**
127
+ * Get the tags in reflection comment
128
+ * @param tag - The tag to find
129
+ * @param reflection - The reflection object
130
+ * @returns The found comment tags or empty array
131
+ */
132
+ export declare function getReflectionTags(tag: td.TagString, reflection: td.Reflection): td.CommentTag[];
package/dist/index.js ADDED
@@ -0,0 +1,192 @@
1
+ /*!
2
+ * typedoc-toolbox v0.0.1
3
+ * MIT License
4
+ * Copyright © 2025-Present Hervé Perchec (https://gitlab.com/herveperchec)
5
+ */
6
+
7
+ import os from 'node:os';
8
+ import fs from 'node:fs/promises';
9
+ import { existsSync } from 'node:fs';
10
+ import path from 'node:path';
11
+ import { utils } from 'juisy';
12
+ import dayjs from 'dayjs';
13
+ import * as td from 'typedoc';
14
+
15
+ class TDOptionError extends Error {
16
+ }
17
+ class TDCompileError extends Error {
18
+ }
19
+ class TDValidationError extends Error {
20
+ }
21
+ class TDOutputError extends Error {
22
+ }
23
+ const dryRunsTempRootDir = path.join(os.tmpdir(), "typedoc-toolbox-dry-runs");
24
+ async function createApp(options = {}, readers = []) {
25
+ return await td.Application.bootstrapWithPlugins({
26
+ // By default, only errors are logged
27
+ logLevel: 3,
28
+ // No entry points
29
+ entryPoints: [],
30
+ // Prevent cleaning output directory
31
+ cleanOutputDir: false,
32
+ ...options
33
+ }, [
34
+ // new td.TypeDocReader(),
35
+ // new td.PackageJsonReader(),
36
+ // new td.TSConfigReader()
37
+ ...readers
38
+ ]);
39
+ }
40
+ function getRawConfig(app) {
41
+ return app.options.getRawValues();
42
+ }
43
+ async function run(app, options) {
44
+ options = options ?? { dry: false };
45
+ if (options.dry) {
46
+ app.logger.info("Dry run started");
47
+ }
48
+ const optionsSnapshot = app.options.snapshot();
49
+ let context;
50
+ const start = Date.now();
51
+ const throwRunError = (error) => {
52
+ logRunSummary(app.logger);
53
+ throw error;
54
+ };
55
+ if (app.logger.hasErrors()) {
56
+ throwRunError(new TDOptionError("TypeDoc option error"));
57
+ }
58
+ if (app.options.getValue("treatWarningsAsErrors") && app.logger.hasWarnings()) {
59
+ throwRunError(new TDOptionError("TypeDoc option error"));
60
+ }
61
+ const getConverterContext = (ctx) => {
62
+ context = ctx;
63
+ };
64
+ app.converter.on(td.Converter.EVENT_END, getConverterContext);
65
+ if (!await app.convert() || app.logger.hasErrors()) {
66
+ throwRunError(new TDCompileError("Compilation error"));
67
+ }
68
+ if (app.options.getValue("treatWarningsAsErrors") && app.logger.hasWarnings()) {
69
+ throwRunError(new TDCompileError("Compilation error"));
70
+ }
71
+ app.converter.off(td.Converter.EVENT_END, getConverterContext);
72
+ const project = context.project;
73
+ const preValidationWarnCount = app.logger.warningCount;
74
+ app.validate(project);
75
+ const hadValidationWarnings = app.logger.warningCount !== preValidationWarnCount || app.logger.validationWarningCount != 0;
76
+ if (app.logger.hasErrors()) {
77
+ throwRunError(new TDValidationError("Validation error"));
78
+ }
79
+ if (hadValidationWarnings && (app.options.getValue("treatWarningsAsErrors") || app.options.getValue("treatValidationWarningsAsErrors"))) {
80
+ throwRunError(new TDValidationError("Validation error"));
81
+ }
82
+ if (app.options.getValue("emit") !== "none") {
83
+ if (options.dry) {
84
+ await dryOutput(app, project);
85
+ } else {
86
+ await app.generateOutputs(project);
87
+ }
88
+ if (app.logger.hasErrors()) {
89
+ throwRunError(new TDOutputError("Output error"));
90
+ }
91
+ if (app.options.getValue("treatWarningsAsErrors") && app.logger.hasWarnings()) {
92
+ throwRunError(new TDOutputError("Output error"));
93
+ }
94
+ }
95
+ app.options.restore(optionsSnapshot);
96
+ app.logger.verbose(`Full run took ${Date.now() - start}ms`);
97
+ return {
98
+ application: app,
99
+ context
100
+ };
101
+ }
102
+ async function dryOutput(app, project) {
103
+ const optionsSnapshot = app.options.snapshot();
104
+ app.options.setValue("cleanOutputDir", false);
105
+ if (!existsSync(dryRunsTempRootDir)) {
106
+ await fs.mkdir(dryRunsTempRootDir);
107
+ }
108
+ const tempDirPath = path.join(dryRunsTempRootDir, dayjs().format("YYYYMMDDHHmmssSSS"));
109
+ await fs.mkdir(tempDirPath);
110
+ try {
111
+ app.logger.info(`Temporary folder "${tempDirPath}" succesfully created`);
112
+ const originalGetOutputSpecs = app.outputs.getOutputSpecs.bind(app.outputs);
113
+ app.outputs.getOutputSpecs = function() {
114
+ return originalGetOutputSpecs().map((outputSpec, index) => {
115
+ const extension = path.extname(outputSpec.path);
116
+ outputSpec.path = utils.path.toPosix(path.join(tempDirPath, `${outputSpec.name}_${index}${extension}`));
117
+ return outputSpec;
118
+ });
119
+ };
120
+ await app.generateOutputs(project);
121
+ app.logger.info(`Temporary folder "${tempDirPath}" succesfully deleted`);
122
+ app.outputs.getOutputSpecs = originalGetOutputSpecs;
123
+ app.options.restore(optionsSnapshot);
124
+ } finally {
125
+ await fs.rm(tempDirPath, { recursive: true, force: true });
126
+ }
127
+ }
128
+ function logRunSummary(logger) {
129
+ const { errorCount, warningCount } = logger;
130
+ if (errorCount) {
131
+ logger.error(
132
+ td.i18n.found_0_errors_and_1_warnings(
133
+ errorCount.toString(),
134
+ warningCount.toString()
135
+ )
136
+ );
137
+ } else if (warningCount) {
138
+ logger.warn(
139
+ td.i18n.found_0_errors_and_1_warnings(
140
+ errorCount.toString(),
141
+ warningCount.toString()
142
+ )
143
+ );
144
+ }
145
+ }
146
+ async function createReflectionUrlResolver(app) {
147
+ const outputSpecs = app.outputs.getOutputSpecs();
148
+ if (outputSpecs.length > 1) {
149
+ throw new Error(`Unable to create reflection URL resolver with multiple outputs [ ${outputSpecs.map((o) => `"${o.name}"`).join(", ")} ]. Please provide only one theme.`);
150
+ } else if (outputSpecs[0].name === "json") {
151
+ throw new Error(`Unable to create reflection URL resolver with JSON output.`);
152
+ }
153
+ const reflectionsCache = {};
154
+ const optionsSnapshot = app.options.snapshot();
155
+ app.options.setValue("emit", "docs");
156
+ let router;
157
+ let getFullUrl;
158
+ app.renderer.on(td.RendererEvent.BEGIN, () => {
159
+ router = app.renderer.router;
160
+ getFullUrl = router.getFullUrl.bind(router);
161
+ });
162
+ const { context } = await run(app, { dry: true });
163
+ app.options.restore(optionsSnapshot);
164
+ return function resolver(identifier) {
165
+ if (!reflectionsCache[identifier]) {
166
+ const tempRefl = new td.DeclarationReflection("__TEMP__", td.ReflectionKind.All, context.project);
167
+ tempRefl.comment = new td.Comment([
168
+ { kind: "inline-tag", tag: "@link", text: identifier }
169
+ ]);
170
+ app.converter.resolveLinks(tempRefl);
171
+ const resolvedTag = tempRefl.comment.summary[0];
172
+ const targetReflection = resolvedTag.target;
173
+ reflectionsCache[resolvedTag.text] = {
174
+ reflection: targetReflection,
175
+ url: targetReflection ? getFullUrl(targetReflection) : void 0
176
+ };
177
+ }
178
+ return reflectionsCache[identifier].url;
179
+ };
180
+ }
181
+ function getReflectionTag(tag, reflection) {
182
+ const comment = reflection.comment;
183
+ if (!comment) return;
184
+ return comment.getTag(tag);
185
+ }
186
+ function getReflectionTags(tag, reflection) {
187
+ const comment = reflection.comment;
188
+ if (!comment) return [];
189
+ return comment.getTags(tag);
190
+ }
191
+
192
+ export { TDCompileError, TDOptionError, TDOutputError, TDValidationError, createApp, createReflectionUrlResolver, dryRunsTempRootDir, getRawConfig, getReflectionTag, getReflectionTags, run };
package/package.json ADDED
@@ -0,0 +1,89 @@
1
+ {
2
+ "name": "typedoc-toolbox",
3
+ "version": "0.0.1",
4
+ "description": "A collection of useful tools for TypeDoc library",
5
+ "type": "module",
6
+ "exports": {
7
+ ".": {
8
+ "types": "./dist/index.d.ts",
9
+ "require": "./dist/index.cjs",
10
+ "import": "./dist/index.js"
11
+ }
12
+ },
13
+ "files": [
14
+ "dist",
15
+ "LICENSE",
16
+ "README.md"
17
+ ],
18
+ "scripts": {
19
+ "build": "vite build",
20
+ "docs:readme": "node ./bin/cli docs generate:readme",
21
+ "docs:api": "node ./bin/cli docs generate:api -c ./docs/config/api/typedoc.config.js",
22
+ "docs:cli": "npm run -s docs:cli:private && npm run -s docs:cli:public",
23
+ "docs:cli:private": "node ./bin/cli docs generate:cli -c ./docs/config/cli/private/config.js",
24
+ "docs:cli:public": "node ./bin/cli docs generate:cli -c ./docs/config/cli/public/config.js",
25
+ "docs": "npm run -s docs:api && npm run -s docs:readme && npm run -s docs:cli",
26
+ "lint": "node ./bin/cli lint",
27
+ "lint:fix": "npm run -s lint -- --fix",
28
+ "lint:markdown": "node ./bin/cli lint:markdown",
29
+ "lint:markdown:fix": "npm run -s lint:markdown -- --fix",
30
+ "release": "node ./bin/cli release",
31
+ "changelog": "node ./bin/cli changelog",
32
+ "git-hooks:reset": "node ./bin/cli git-hooks reset",
33
+ "git-hooks:sync": "node ./bin/cli git-hooks sync",
34
+ "test": "node ./bin/cli test run",
35
+ "test:watch": "node ./bin/cli test",
36
+ "test:ui": "npm run -s test:watch -- --ui --coverage.enabled=true",
37
+ "test:coverage": "npm run -s test -- --coverage.enabled=true"
38
+ },
39
+ "repository": {
40
+ "type": "git",
41
+ "url": "git+https://gitlab.com/hperchec/typedoc-toolbox.git"
42
+ },
43
+ "author": {
44
+ "name": "Hervé Perchec",
45
+ "url": "https://gitlab.com/herveperchec"
46
+ },
47
+ "license": "MIT",
48
+ "bugs": {
49
+ "url": "https://gitlab.com/hperchec/typedoc-toolbox/issues"
50
+ },
51
+ "homepage": "https://gitlab.com/hperchec/typedoc-toolbox",
52
+ "keywords": [
53
+ "typedoc",
54
+ "typedoc-plugin",
55
+ "tool",
56
+ "tools",
57
+ "toolbox",
58
+ "api",
59
+ "documentation"
60
+ ],
61
+ "dependencies": {
62
+ "dayjs": "^1.11.19",
63
+ "juisy": "^2.2.0",
64
+ "typedoc": "^0.28.16"
65
+ },
66
+ "devDependencies": {
67
+ "@release-it/conventional-changelog": "^9.0.4",
68
+ "@vitest/coverage-v8": "^3",
69
+ "@vitest/ui": "^3",
70
+ "eslint-plugin-jsdoc": "^50.8.0",
71
+ "eslint-plugin-tsdoc": "^0.5.0",
72
+ "remark-insert-headings": "^0.0.0",
73
+ "remark-toc": "^9.0.0",
74
+ "simple-git-hooks": "^2.13.1",
75
+ "typedoc-plugin-default-groups": "^1.0.2",
76
+ "typedoc-plugin-dt-links": "^2.0.39",
77
+ "typedoc-plugin-import-target": "^1.3.2",
78
+ "typedoc-plugin-markdown": "^4.9.0",
79
+ "typedoc-plugin-mdn-links": "^5.1.1",
80
+ "typedoc-plugin-remark": "^2.0.1",
81
+ "typescript-eslint": "^8.39.1",
82
+ "vite-plugin-checker": "^0.11.0",
83
+ "vite-plugin-dts": "^4.5.4",
84
+ "vitest": "^3"
85
+ },
86
+ "peerDependencies": {
87
+ "typedoc": "^0.28.16"
88
+ }
89
+ }