Skip to content

Commit c0182dd

Browse files
committed
Permit functions as values in the plugin option
1 parent f60f0a4 commit c0182dd

File tree

14 files changed

+180
-44
lines changed

14 files changed

+180
-44
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ title: Changelog
66

77
### Features
88

9+
- If using JS config files, the `plugin` function can now be given plugin functions to load.
910
- Permit `-` within tag names to support `typescript-json-schema`'s `@TJS-type` tag, #2972.
1011

1112
### Thanks!

scripts/clone_api_users.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ if (import.meta.url.endsWith(process.argv[1])) {
9393
}
9494

9595
console.log(`Cloning/updating took ${(Date.now() - start) / 1000} seconds`);
96+
console.log(`Output is in ${args.values.output}`);
9697

9798
// Check for repos listed in the wrong list
9899
const currentMinor = semver.parse(JSON.parse(readFileSync("package.json", "utf-8")).version)?.minor;

scripts/generate_options_schema.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ addTypeDocOptions({
3636
case ParameterType.GlobArray:
3737
case ParameterType.PathArray:
3838
case ParameterType.ModuleArray:
39+
case ParameterType.PluginArray:
3940
data.type = "array";
4041
data.items = { type: "string" };
4142
data.default = /** @type {import("../dist/index.js").ArrayDeclarationOption} */ (

scripts/generate_site_plugins.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ const NEXT_BREAKING_TYPEDOC_VERSION = semver.parse(TYPEDOC_VERSION)?.inc("minor"
88
if (!NEXT_BREAKING_TYPEDOC_VERSION) {
99
throw new Error("Failed to determine next TypeDoc version");
1010
}
11-
console.log(NEXT_BREAKING_TYPEDOC_VERSION);
1211

1312
const CACHE_ROOT = "tmp/site-cache";
1413
mkdirSync(CACHE_ROOT, { recursive: true });

site/options/configuration.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,3 +106,6 @@ typedoc --plugin ./custom-plugin.js
106106

107107
Specifies the plugins that should be loaded. By default, no plugins are loaded.
108108
See [Plugins](../plugins.md) for a list of available plugins.
109+
110+
If using a JavaScript configuration file, the `plugin` option may be given
111+
a function which will be called to load a plugin.

site/tags/sortStrategy.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ title: "@sortStrategy"
44

55
# @sortStrategy
66

7-
**Tag Kind:** [Block](../tags.md#Block-tags) <br>
7+
**Tag Kind:** [Block](../tags.md#block-tags) <br>
88

99
This tag can be used to override the [sort](../options/organization.md#sort) locally
1010
for a module, namespace, class, or interface. The override will be applied to direct

src/lib/internationalization/locales/en.cts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,7 @@ export = {
414414
favicon_must_have_one_of_the_following_extensions_0: "Favicon must have one of the following extensions: {0}",
415415
option_0_must_be_an_object: "The '{0}' option must be a non-array object",
416416
option_0_must_be_an_array_of_string: "The '{0}' option must be set to an array of strings",
417+
option_0_must_be_an_array_of_string_or_functions: "The '{0}' option must be set to an array of strings/functions",
417418
option_0_must_be_a_function: "The '{0}' option must be a function",
418419
option_0_must_be_object_with_urls: `{0} must be an object with string labels as keys and URL values`,
419420
visibility_filters_only_include_0: `visibilityFilters can only include the following non-@ keys: {0}`,

src/lib/utils-common/path.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
import { assert } from "./general.js";
22

3+
// Type only import is permitted
4+
// eslint-disable-next-line no-restricted-importsgn
5+
import type { Application } from "../application.js";
6+
37
/**
48
* Represents a normalized path with path separators being `/`
59
* On Windows, drives are represented like `C:/Users` for consistency
@@ -15,6 +19,12 @@ export type NormalizedPath = "" | "/" | string & { readonly __normPath: unique s
1519
*/
1620
export type NormalizedPathOrModule = NormalizedPath | string & { readonly __normPathOrModule: unique symbol };
1721

22+
/**
23+
* Represents either a {@link NormalizedPath} or a Node module name
24+
* (e.g. `typedoc-plugin-mdn-links` or `@gerrit0/typedoc-plugin`)
25+
*/
26+
export type NormalizedPathOrModuleOrFunction = NormalizedPathOrModule | ((app: Application) => Promise<void> | void);
27+
1828
/**
1929
* Represents a glob path configured by a user.
2030
*/

src/lib/utils/options/declaration.ts

Lines changed: 54 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,12 @@ import {
1010
type NeverIfInternal,
1111
type NormalizedPath,
1212
type NormalizedPathOrModule,
13+
type NormalizedPathOrModuleOrFunction,
1314
type TranslatedString,
1415
} from "#utils";
1516
import type { TranslationProxy } from "../../internationalization/internationalization.js";
1617
import { createGlobString, normalizePath } from "../paths.js";
18+
import type { Application } from "../../application.js";
1719

1820
/** @enum */
1921
export const EmitStrategy = {
@@ -122,7 +124,8 @@ export type TypeDocOptions = {
122124
TypeDocOptionMap[K] extends ManuallyValidatedOption<
123125
infer ManuallyValidated
124126
> ? ManuallyValidated :
125-
TypeDocOptionMap[K] extends NormalizedPath[] | NormalizedPathOrModule[] | GlobString[] ? string[] :
127+
TypeDocOptionMap[K] extends
128+
NormalizedPath[] | NormalizedPathOrModule[] | NormalizedPathOrModuleOrFunction[] | GlobString[] ? string[] :
126129
TypeDocOptionMap[K] extends NormalizedPath ? string :
127130
TypeDocOptionMap[K] extends
128131
| string
@@ -150,6 +153,8 @@ export type TypeDocOptionValues = {
150153
| string
151154
| string[]
152155
| GlobString[]
156+
| NormalizedPathOrModule[]
157+
| NormalizedPathOrModuleOrFunction[]
153158
| number
154159
| boolean
155160
| Record<string, boolean> ? TypeDocOptionMap[K] :
@@ -183,7 +188,7 @@ export interface TypeDocOptionMap {
183188
options: NormalizedPath;
184189
tsconfig: NormalizedPath;
185190
compilerOptions: unknown;
186-
plugin: NormalizedPathOrModule[];
191+
plugin: NormalizedPathOrModuleOrFunction[];
187192
lang: string;
188193
locales: ManuallyValidatedOption<Record<string, Record<string, string>>>;
189194
packageOptions: ManuallyValidatedOption<
@@ -404,7 +409,9 @@ export type KeyToDeclaration<K extends keyof TypeDocOptionMap> = TypeDocOptionMa
404409
TypeDocOptionMap[K] extends string | NormalizedPath ? StringDeclarationOption :
405410
TypeDocOptionMap[K] extends number ? NumberDeclarationOption :
406411
TypeDocOptionMap[K] extends GlobString[] ? GlobArrayDeclarationOption :
407-
TypeDocOptionMap[K] extends string[] | NormalizedPath[] | NormalizedPathOrModule[] ? ArrayDeclarationOption :
412+
TypeDocOptionMap[K] extends
413+
string[] | NormalizedPath[] | NormalizedPathOrModule[] | NormalizedPathOrModuleOrFunction[] ?
414+
ArrayDeclarationOption :
408415
unknown extends TypeDocOptionMap[K] ? MixedDeclarationOption | ObjectDeclarationOption :
409416
TypeDocOptionMap[K] extends ManuallyValidatedOption<unknown> ?
410417
| (MixedDeclarationOption & {
@@ -452,8 +459,14 @@ export enum ParameterType {
452459
PathArray,
453460
/**
454461
* Resolved according to the config directory if it starts with `.`
462+
* @deprecated since 0.28.8, will be removed in 0.29
455463
*/
456464
ModuleArray,
465+
/**
466+
* Resolved according to the config directory if it starts with `.`
467+
* @internal - only intended for use with the plugin option
468+
*/
469+
PluginArray,
457470
/**
458471
* Relative to the config directory.
459472
*/
@@ -567,7 +580,8 @@ export interface ArrayDeclarationOption extends DeclarationOptionBase {
567580
type:
568581
| ParameterType.Array
569582
| ParameterType.PathArray
570-
| ParameterType.ModuleArray;
583+
| ParameterType.ModuleArray
584+
| ParameterType.PluginArray;
571585

572586
/**
573587
* If not specified defaults to an empty array.
@@ -674,6 +688,7 @@ export interface ParameterTypeToOptionTypeMap {
674688
[ParameterType.Array]: string[];
675689
[ParameterType.PathArray]: NormalizedPath[];
676690
[ParameterType.ModuleArray]: NormalizedPathOrModule[];
691+
[ParameterType.PluginArray]: Array<NormalizedPathOrModule | ((app: Application) => void | Promise<void>)>;
677692
[ParameterType.GlobArray]: GlobString[];
678693
[ParameterType.Flags]: Record<string, boolean>;
679694

@@ -685,7 +700,7 @@ export type DeclarationOptionToOptionType<T extends DeclarationOption> = T exten
685700
T extends FlagsDeclarationOption<infer U> ? U :
686701
ParameterTypeToOptionTypeMap[Exclude<T["type"], undefined>];
687702

688-
function toStringArray(value: unknown, option: DeclarationOption) {
703+
function toStringArray(value: unknown, option: DeclarationOption): string[] {
689704
if (Array.isArray(value) && value.every(v => typeof v === "string")) {
690705
return value;
691706
} else if (typeof value === "string") {
@@ -695,6 +710,19 @@ function toStringArray(value: unknown, option: DeclarationOption) {
695710
throw new Error(i18n.option_0_must_be_an_array_of_string(option.name));
696711
}
697712

713+
function toStringOrFunctionArray(
714+
value: unknown,
715+
option: DeclarationOption,
716+
): Array<string | ((app: Application) => void | Promise<void>)> {
717+
if (Array.isArray(value) && value.every(v => typeof v === "string" || typeof v === "function")) {
718+
return value;
719+
} else if (typeof value === "string") {
720+
return [value];
721+
}
722+
723+
throw new Error(i18n.option_0_must_be_an_array_of_string_or_functions(option.name));
724+
}
725+
698726
const converters: {
699727
[K in ParameterType]: (
700728
value: unknown,
@@ -763,6 +791,13 @@ const converters: {
763791
option.validate?.(resolved);
764792
return resolved;
765793
},
794+
[ParameterType.PluginArray](value, option, configPath) {
795+
const arrayValue = toStringOrFunctionArray(value, option);
796+
const resolved = arrayValue.map(plugin =>
797+
typeof plugin === "function" ? plugin : resolveModulePath(plugin, configPath)
798+
);
799+
return resolved;
800+
},
766801
[ParameterType.GlobArray](value, option, configPath) {
767802
const toGlobString = (v: unknown) => {
768803
const s = String(v);
@@ -942,6 +977,12 @@ const defaultGetters: {
942977
}
943978
return [];
944979
},
980+
[ParameterType.PluginArray](option) {
981+
if (option.defaultValue) {
982+
return resolveModulePaths(option.defaultValue, process.cwd());
983+
}
984+
return [];
985+
},
945986
[ParameterType.GlobArray](option) {
946987
return (option.defaultValue ?? []).map(g => createGlobString(normalizePath(process.cwd()), g));
947988
},
@@ -959,12 +1000,14 @@ export function getDefaultValue(option: DeclarationOption) {
9591000
}
9601001

9611002
function resolveModulePaths(modules: readonly string[], configPath: string): NormalizedPathOrModule[] {
962-
return modules.map((path) => {
963-
if (path.startsWith(".")) {
964-
return normalizePath(resolve(configPath, path));
965-
}
966-
return normalizePath(path);
967-
});
1003+
return modules.map(path => resolveModulePath(path, configPath));
1004+
}
1005+
1006+
function resolveModulePath(path: string, configPath: string): NormalizedPathOrModule {
1007+
if (path.startsWith(".")) {
1008+
return normalizePath(resolve(configPath, path));
1009+
}
1010+
return normalizePath(path);
9681011
}
9691012

9701013
function isTsNumericEnum(map: Record<string, any>) {

src/lib/utils/options/readers/arguments.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ const ARRAY_OPTION_TYPES = new Set<ParameterType | undefined>([
77
ParameterType.Array,
88
ParameterType.PathArray,
99
ParameterType.ModuleArray,
10+
ParameterType.PluginArray,
1011
ParameterType.GlobArray,
1112
]);
1213

0 commit comments

Comments
 (0)