From 6aae94e6c5099b338cf9e581c323eb510db6aa77 Mon Sep 17 00:00:00 2001 From: Soc Sieng Date: Sun, 26 Jan 2020 14:19:02 -0800 Subject: [PATCH] fix: Plugin resolution for relative paths Resolve plugin modules relative to the current path instead of the internal path. Fixes #1188 --- src/lib/utils/plugins.ts | 27 ++++++++++++++++++++++++++- src/test/plugin-host.test.ts | 24 ++++++++++++++++++++++++ src/test/plugins/absolute.ts | 4 ++++ src/test/plugins/relative.ts | 4 ++++ 4 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 src/test/plugins/absolute.ts create mode 100644 src/test/plugins/relative.ts diff --git a/src/lib/utils/plugins.ts b/src/lib/utils/plugins.ts index dbde61422..f2c746a93 100644 --- a/src/lib/utils/plugins.ts +++ b/src/lib/utils/plugins.ts @@ -20,7 +20,7 @@ export class PluginHost extends AbstractComponent { */ load(): boolean { const logger = this.application.logger; - const plugins = this.plugins.length ? this.plugins : this.discoverNpmPlugins(); + const plugins = this.plugins.length ? this.resolvePluginPaths(this.plugins) : this.discoverNpmPlugins(); if (plugins.some(plugin => plugin.toLowerCase() === 'none')) { return true; @@ -133,4 +133,29 @@ export class PluginHost extends AbstractComponent { return false; } } + + /** + * Resolves plugin paths to absolute paths from the current working directory + * (`process.cwd()`). + * + * ```txt + * ./plugin -> resolve + * ../plugin -> resolve + * plugin -> don't resolve (module resolution) + * /plugin -> don't resolve (already absolute path) + * c:\plugin -> don't resolve (already absolute path) + * ``` + * + * @param plugins + */ + private resolvePluginPaths(plugins: string[]) { + const cwd = process.cwd(); + return plugins.map(plugin => { + // treat plugins that start with `.` as relative, requiring resolution + if (plugin.startsWith('.')) { + return Path.resolve(cwd, plugin); + } + return plugin; + }); + } } diff --git a/src/test/plugin-host.test.ts b/src/test/plugin-host.test.ts index 140af2792..fd5d8c112 100644 --- a/src/test/plugin-host.test.ts +++ b/src/test/plugin-host.test.ts @@ -1,6 +1,7 @@ import { Application } from '..'; import Assert = require('assert'); import * as mockery from 'mockery'; +import * as path from 'path'; describe('PluginHost', function () { before (function () { @@ -27,4 +28,27 @@ describe('PluginHost', function () { 'typedoc-plugin-2' ]); }); + + it('loads a plugin with relative path', function () { + const app = new Application(); + app.bootstrap({ + plugin: ['./dist/test/plugins/relative'] + }); + + Assert.deepEqual(app.plugins.plugins, [ + './dist/test/plugins/relative' + ]); + }); + + it('loads a plugin with absolute path', function () { + const app = new Application(); + const absolutePath = path.resolve(__dirname, './plugins/absolute'); + app.bootstrap({ + plugin: [absolutePath] + }); + + Assert.deepEqual(app.plugins.plugins, [ + absolutePath + ]); + }); }); diff --git a/src/test/plugins/absolute.ts b/src/test/plugins/absolute.ts new file mode 100644 index 000000000..2d34ff1f0 --- /dev/null +++ b/src/test/plugins/absolute.ts @@ -0,0 +1,4 @@ +import { Application } from '../..'; + +module.exports = (pluginHost: Application) => { +}; diff --git a/src/test/plugins/relative.ts b/src/test/plugins/relative.ts new file mode 100644 index 000000000..2d34ff1f0 --- /dev/null +++ b/src/test/plugins/relative.ts @@ -0,0 +1,4 @@ +import { Application } from '../..'; + +module.exports = (pluginHost: Application) => { +};