diff --git a/packages/typedoc-plugin-appium/lib/converter/builder.ts b/packages/typedoc-plugin-appium/lib/converter/builder.ts index 6fce406cf..206ea578b 100644 --- a/packages/typedoc-plugin-appium/lib/converter/builder.ts +++ b/packages/typedoc-plugin-appium/lib/converter/builder.ts @@ -4,8 +4,15 @@ * @module */ +import _ from 'lodash'; import pluralize from 'pluralize'; -import {ContainerReflection, Context, DeclarationReflection, ProjectReflection} from 'typedoc'; +import { + ContainerReflection, + Context, + DeclarationReflection, + ProjectReflection, + ReflectionKind, +} from 'typedoc'; import {isParentReflection} from '../guards'; import {AppiumPluginLogger} from '../logger'; import { @@ -19,6 +26,7 @@ import { ProjectCommands, Route, } from '../model'; +import {NAME_BUILTIN_COMMAND_MODULE} from './builtin-method-map'; import {findChildByNameAndGuard} from './utils'; /** @@ -58,7 +66,6 @@ export function createCommandReflection( * Note that the return value is mainly for informational purposes, since this method mutates * TypeDoc's state. * @param log - Logger - * @param ctx - Current context * @param parent - Parent module (or project) * @param moduleCmds - Command information for `module` * @internal @@ -66,11 +73,11 @@ export function createCommandReflection( export function createExtensionReflection( log: AppiumPluginLogger, ctx: Context, - parent: ParentReflection, + name: string, moduleCmds: ModuleCommands ): ExtensionReflection { // TODO: parent.name may not be right here - const extRefl = new ExtensionReflection(parent.name, parent, moduleCmds); + const extRefl = new ExtensionReflection(name, ctx.project, moduleCmds); /** * See note in {@link createCommandReflection} above about this call */ @@ -121,7 +128,7 @@ export function createReflections( ? project : findChildByNameAndGuard(project, parentName, isParentReflection)!; - const cmdsRefl = createExtensionReflection(log, ctx, parentRefl, parentCmds); + const cmdsRefl = createExtensionReflection(log, ctx, parentRefl.name, parentCmds); log.info( '(%s) Created %d new command %s', @@ -152,3 +159,29 @@ export function omitDefaultReflections( return removed; } + +/** + * Removes extension reflection(s) which are part of Appium itself. This is desirable for most + * extension authors. + * @param project - Current TypeDoc project + * @param refl - A {@linkcode ContainerReflection} to remove children from; defaults to `project` + * @returns A set of removed {@linkcode DeclarationReflection}s + */ +export function omitBuiltinReflections( + project: ProjectReflection, + refl: ContainerReflection = project +) { + let removed = new Set(); + + const extRefls = refl.getChildrenByKind( + AppiumPluginReflectionKind.Extension as any + ) as DeclarationReflection[]; + const builtinRefl = _.find(extRefls, {name: NAME_BUILTIN_COMMAND_MODULE}); + if (!builtinRefl) { + throw new Error(`Could not find builtin commands reflection "${NAME_BUILTIN_COMMAND_MODULE}"`); + } + project.removeReflection(builtinRefl); + removed.add(builtinRefl); + + return removed; +} diff --git a/packages/typedoc-plugin-appium/lib/index.ts b/packages/typedoc-plugin-appium/lib/index.ts index 0d9fcadf6..ebcc59eae 100644 --- a/packages/typedoc-plugin-appium/lib/index.ts +++ b/packages/typedoc-plugin-appium/lib/index.ts @@ -4,13 +4,21 @@ */ import _ from 'lodash'; +import pluralize from 'pluralize'; import {Application, Context, Converter, DeclarationReflection} from 'typedoc'; -import {convertCommands, createReflections, omitDefaultReflections} from './converter'; +import { + convertCommands, + createReflections, + omitBuiltinReflections, + omitDefaultReflections, +} from './converter'; import {AppiumPluginLogger, AppiumPluginParentLogger} from './logger'; import {ExtensionReflection, NS, ProjectCommands} from './model'; import {configureOptions, declarations} from './options'; import {configureTheme, THEME_NAME} from './theme'; +let log: AppiumPluginLogger; + /** * Loads the Appium TypeDoc plugin. * @@ -48,7 +56,7 @@ export async function convert(app: Application): Promise { let projectCommands: ProjectCommands | undefined; // we don't want to do this work if we're not using the custom theme! - const log = new AppiumPluginLogger(app.logger, NS); + log = log ?? new AppiumPluginLogger(app.logger, NS); // this should not be necessary given the `AppiumPluginOptionsReader` forces the issue, but // it's a safeguard nonetheless. @@ -98,12 +106,22 @@ export interface ConvertResult { * @returns Typedoc `Context` at the time of the {@linkcode Converter.EVENT_RESOLVE_END} event */ export async function postProcess(app: Application): Promise { + log = log ?? new AppiumPluginLogger(app.logger, NS); return new Promise((resolve) => { app.converter.once(Converter.EVENT_RESOLVE_END, (ctx: Context) => { let removed: Set | undefined; // if the `outputModules` option is false, then we want to remove all the usual TypeDoc reflections. if (!app.options.getValue(declarations.outputModules.name)) { removed = omitDefaultReflections(ctx.project); + log.info('%s omitted from output', pluralize('default reflection', removed.size, true)); + } + if (!app.options.getValue(declarations.outputBuiltinCommands.name)) { + const removedBuiltinRefls = omitBuiltinReflections(ctx.project); + removed = new Set([...(removed ?? []), ...removedBuiltinRefls]); + log.info( + '%s omitted from output', + pluralize('builtin reflection', removedBuiltinRefls.size, true) + ); } resolve({ctx, removed}); }); diff --git a/packages/typedoc-plugin-appium/test/e2e/index.e2e.spec.ts b/packages/typedoc-plugin-appium/test/e2e/index.e2e.spec.ts index ecd0507ad..fa283a88c 100644 --- a/packages/typedoc-plugin-appium/test/e2e/index.e2e.spec.ts +++ b/packages/typedoc-plugin-appium/test/e2e/index.e2e.spec.ts @@ -1,3 +1,4 @@ +import _ from 'lodash'; import { Application, Context, @@ -127,6 +128,7 @@ describe('@appium/typedoc-plugin-appium', function () { before(async function () { const app = reset(); app.options.setValue('outputModules', true); + app.options.setValue('outputBuiltinCommands', true); // do not pollute result resolveBeginCtxPromise = convert(app); resolveEndCtxPromise = postProcess(app); app.convert(); @@ -147,5 +149,28 @@ describe('@appium/typedoc-plugin-appium', function () { expect(removed).to.be.undefined; }); }); + + describe('when the `outputBuiltinCommands` option is false', function () { + before(async function () { + const app = reset(); + app.options.setValue('outputModules', true); // as to not pollute the 'removed' set + app.options.setValue('outputBuiltinCommands', false); + resolveBeginCtxPromise = convert(app); + resolveEndCtxPromise = postProcess(app); + app.convert(); + [, {ctx, removed}] = await Promise.all([resolveBeginCtxPromise, resolveEndCtxPromise]); + ({project} = ctx); + }); + + it('should remove the builtin commands', function () { + expect(removed).to.have.lengthOf(1); + }); + + it('should not output builtin commands', async function () { + const extRefls = project.getChildrenByKind(AppiumPluginReflectionKind.Extension as any); + expect(extRefls).to.not.be.empty; + expect(_.find(extRefls, {name: NAME_BUILTIN_COMMAND_MODULE})).to.be.undefined; + }); + }); }); });