Skip to content

Commit 83e64aa

Browse files
mrkurtaciccarello
authored andcommitted
Support for scoped npm plugins (#736)
The plugin discovery function needs to check directories in `node_modules`, and also any directorys in `node_modules/@scope`.
1 parent 1d9e8f2 commit 83e64aa

File tree

1 file changed

+16
-7
lines changed

1 file changed

+16
-7
lines changed

src/lib/utils/plugins.ts

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { Application } from '../application';
66
import { AbstractComponent, Component, Option } from './component';
77
import { ParameterType } from './options/declaration';
88

9-
@Component({name: 'plugin-host', internal: true})
9+
@Component({ name: 'plugin-host', internal: true })
1010
export class PluginHost extends AbstractComponent<Application> {
1111
@Option({
1212
name: 'plugin',
@@ -42,9 +42,9 @@ export class PluginHost extends AbstractComponent<Application> {
4242
try {
4343
const instance = require(plugin);
4444
const initFunction = typeof instance.load === 'function'
45-
? instance.load
46-
: instance // support legacy plugins
47-
;
45+
? instance.load
46+
: instance // support legacy plugins
47+
;
4848
if (typeof initFunction === 'function') {
4949
instance(this);
5050
logger.write('Loaded plugin %s', plugin);
@@ -89,16 +89,25 @@ export class PluginHost extends AbstractComponent<Application> {
8989
* Scan the given `node_modules` directory for TypeDoc plugins.
9090
*/
9191
function discoverModules(basePath: string) {
92+
const candidates: string[] = [];
9293
FS.readdirSync(basePath).forEach((name) => {
9394
const dir = Path.join(basePath, name);
94-
const infoFile = Path.join(dir, 'package.json');
95+
if (name.startsWith('@')) {
96+
FS.readdirSync(dir).forEach((n) => {
97+
candidates.push(Path.join(name, n));
98+
});
99+
}
100+
candidates.push(name);
101+
});
102+
candidates.forEach((name) => {
103+
const infoFile = Path.join(basePath, name, 'package.json');
95104
if (!FS.existsSync(infoFile)) {
96105
return;
97106
}
98107

99108
const info = loadPackageInfo(infoFile);
100109
if (isPlugin(info)) {
101-
result.push(name);
110+
result.push(Path.join(basePath, name));
102111
}
103112
});
104113
}
@@ -108,7 +117,7 @@ export class PluginHost extends AbstractComponent<Application> {
108117
*/
109118
function loadPackageInfo(fileName: string): any {
110119
try {
111-
return JSON.parse(FS.readFileSync(fileName, {encoding: 'utf-8'}));
120+
return JSON.parse(FS.readFileSync(fileName, { encoding: 'utf-8' }));
112121
} catch (error) {
113122
logger.error('Could not parse %s', fileName);
114123
return {};

0 commit comments

Comments
 (0)