Skip to content

Commit

Permalink
feat: set up initial behavior
Browse files Browse the repository at this point in the history
  • Loading branch information
RebeccaStevens committed Feb 24, 2023
1 parent d00c1d2 commit 55dbb51
Show file tree
Hide file tree
Showing 4 changed files with 144 additions and 3 deletions.
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -2,5 +2,6 @@ node_modules/

/coverage/
/dist/
/docs/

*.log
4 changes: 4 additions & 0 deletions package.json
Expand Up @@ -100,7 +100,11 @@
"rollup-plugin-dts": "5.2.0",
"semantic-release": "20.1.0",
"ts-node": "10.9.1",
"typedoc": "^0.23.25",
"typescript": "4.9.5"
},
"peerDependencies": {
"typedoc": "^0.23.25"
},
"packageManager": "pnpm@7.27.0"
}
41 changes: 41 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

101 changes: 98 additions & 3 deletions src/index.ts
@@ -1,4 +1,99 @@
/* eslint-disable eslint-comments/disable-enable-pair */
/* eslint-disable unicorn/no-empty-file */
import type { Application, ProjectReflection, Reflection } from "typedoc";
import { ParameterType, Validator, ReflectionKind } from "typedoc";

// Write me
/**
* Extend typedoc's options with the plugin's option using declaration merging.
*/
declare module "typedoc" {
// eslint-disable-next-line @typescript-eslint/consistent-type-definitions, jsdoc/require-jsdoc
export interface TypeDocOptionMap {
requireTags: {
byKind: ByKindEntry[];
};
}
}

export type ByKindEntry = {
kind: keyof typeof ReflectionKind;
tags: string[];
};

export function load(app: Readonly<Application>) {
// @ts-expect-error -- FIXME: ???
app.options.addDeclaration({
name: "requireTags",
help: "The configuration object of the require-tags plugin.",
type: ParameterType.Object,
});

app.validator.on(
Validator.EVENT_RUN,
(project: Readonly<ProjectReflection>) => {
const requireTagsOptions = app.options.getValue(
"requireTags"
) as unknown as {
byKind: ByKindEntry[];
};

let m_kinds = requireTagsOptions.byKind.reduce(
(prev, cur) => prev | ReflectionKind[cur.kind],
0
);

const reflectionKindReplacements: Array<
[oldKind: number, newKind: number]
> = [
[ReflectionKind.FunctionOrMethod, ReflectionKind.CallSignature],
[ReflectionKind.Constructor, ReflectionKind.ConstructorSignature],
[
ReflectionKind.Accessor,
ReflectionKind.GetSignature | ReflectionKind.SetSignature,
],
];

for (const [oldKind, newKind] of reflectionKindReplacements) {
m_kinds = (m_kinds | newKind) & ~oldKind;
}

const requireTagsByKind = new Map<number, string[]>(
requireTagsOptions.byKind.map(
({ kind: kindString, tags }): [number, string[]] => {
const kind = ReflectionKind[kindString];
const realKind =
reflectionKindReplacements.find(
([oldKind]) => (oldKind & kind) !== 0
)?.[1] ?? kind;
return [realKind, tags];
}
)
);

const reflections = project.getReflectionsByKind(m_kinds);
const seen = new Set<Reflection>();

for (const reflection of reflections) {
if (seen.has(reflection)) {
continue;
}

seen.add(reflection);

if (!reflection.hasComment()) {
app.logger.warn(
`${reflection.getFriendlyFullName()} does not have any documentation.`
);
continue;
}

for (const tagName of requireTagsByKind.get(reflection.kind)!) {
const tag = `@${tagName}` as const;
if (reflection.comment!.getTags(tag).length === 0) {
app.logger.warn(
`${reflection.getFriendlyFullName()} does not have any ${tag} tags.`
);
}
}
}
}
);
}

0 comments on commit 55dbb51

Please sign in to comment.