Skip to content

Commit

Permalink
feat: set up initial behavior (#1)
Browse files Browse the repository at this point in the history
  • Loading branch information
RebeccaStevens committed Mar 2, 2023
1 parent 4dbaa8a commit 8806846
Show file tree
Hide file tree
Showing 8 changed files with 240 additions and 25 deletions.
4 changes: 2 additions & 2 deletions .github/FUNDING.yml
@@ -1,3 +1,3 @@
issuehunt: RebeccaStevens/typedoc-plugin-require-tags
issuehunt: RebeccaStevens/typedoc-plugin-custom-validation
ko_fi: rebeccastevens
custom: https://github.com/RebeccaStevens/typedoc-plugin-require-tags/blob/main/DONATIONS.md
custom: https://github.com/RebeccaStevens/typedoc-plugin-custom-validation/blob/main/DONATIONS.md
2 changes: 1 addition & 1 deletion .github/workflows/build-node.yml
Expand Up @@ -11,4 +11,4 @@ jobs:
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/prepare
- run: pnpm run build-node
- run: pnpm run build:node
9 changes: 4 additions & 5 deletions .github/workflows/release.yml
Expand Up @@ -49,8 +49,7 @@ jobs:
run: pnpm run build

- name: Release
run: echo "Do Release Here"
# run: pnpm run semantic-release
# env:
# GITHUB_TOKEN: ${{ github.token }}
# NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
run: pnpm run semantic-release
env:
GITHUB_TOKEN: ${{ github.token }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -2,5 +2,6 @@ node_modules/

/coverage/
/dist/
/docs/

*.log
64 changes: 55 additions & 9 deletions README.md
@@ -1,13 +1,13 @@
<div align="center">

# typedoc-plugin-require-tags
# typedoc-plugin-custom-validation

[![npm version](https://img.shields.io/npm/v/typedoc-plugin-require-tags.svg)](https://www.npmjs.com/package/typedoc-plugin-require-tags)
[![CI](https://github.com/RebeccaStevens/typedoc-plugin-require-tags/actions/workflows/release.yml/badge.svg)](https://github.com/RebeccaStevens/typedoc-plugin-require-tags/actions/workflows/release.yml)
[![Coverage Status](https://codecov.io/gh/RebeccaStevens/typedoc-plugin-require-tags/branch/main/graph/badge.svg?token=MVpR1oAbIT)](https://codecov.io/gh/RebeccaStevens/typedoc-plugin-require-tags)\
[![npm version](https://img.shields.io/npm/v/typedoc-plugin-custom-validation.svg)](https://www.npmjs.com/package/typedoc-plugin-custom-validation)
[![CI](https://github.com/RebeccaStevens/typedoc-plugin-custom-validation/actions/workflows/release.yml/badge.svg)](https://github.com/RebeccaStevens/typedoc-plugin-custom-validation/actions/workflows/release.yml)
[![Coverage Status](https://codecov.io/gh/RebeccaStevens/typedoc-plugin-custom-validation/branch/main/graph/badge.svg?token=MVpR1oAbIT)](https://codecov.io/gh/RebeccaStevens/typedoc-plugin-custom-validation)\
[![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square)](https://github.com/prettier/prettier)
[![GitHub Discussions](https://img.shields.io/github/discussions/RebeccaStevens/typedoc-plugin-require-tags?style=flat-square)](https://github.com/RebeccaStevens/typedoc-plugin-require-tags/discussions)
[![BSD 3 Clause license](https://img.shields.io/github/license/RebeccaStevens/typedoc-plugin-require-tags.svg?style=flat-square)](https://opensource.org/licenses/BSD-3-Clause)
[![GitHub Discussions](https://img.shields.io/github/discussions/RebeccaStevens/typedoc-plugin-custom-validation?style=flat-square)](https://github.com/RebeccaStevens/typedoc-plugin-custom-validation/discussions)
[![BSD 3 Clause license](https://img.shields.io/github/license/RebeccaStevens/typedoc-plugin-custom-validation.svg?style=flat-square)](https://opensource.org/licenses/BSD-3-Clause)
[![Commitizen friendly](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg?style=flat-square)](https://commitizen.github.io/cz-cli/)
[![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg?style=flat-square)](https://github.com/semantic-release/semantic-release)

Expand All @@ -21,11 +21,57 @@

```sh
# Install with npm
npm install -D typedoc-plugin-require-tags
npm install -D typedoc-plugin-custom-validation

# Install with pnpm
pnpm add -D typedoc-plugin-require-tags
pnpm add -D typedoc-plugin-custom-validation

# Install with yarn
yarn add -D typedoc-plugin-require-tags
yarn add -D typedoc-plugin-custom-validation
```

## Usage

All options are configured in the `customValidation` option.

### `byKind`

This option is for specifying requirements for each kind of node.

Example: Require all functions to have a summary and have an `@example` tag.

```json
{
"plugin": ["typedoc-plugin-custom-validation"],
"customValidation": {
"byKind": [
{
"kinds": "Function",
"summary": true,
"tags": ["example"]
}
]
}
}
```

### My Tags Don't Exists?

Due to the way typedoc works, some tags may be move to other nodes than the one they were defined on.

For example, `@param` tags are removed from the `Function` node they are defined on and its content is put onto the corresponding `Parameter` node.
You can require parameters to be documented with:

```json
{
"plugin": ["typedoc-plugin-custom-validation"],
"customValidation": {
"byKind": [
{
"kinds": "Parameter",
"summary": true
}
]
}
}
```
16 changes: 11 additions & 5 deletions package.json
@@ -1,16 +1,18 @@
{
"name": "typedoc-plugin-require-tags",
"name": "typedoc-plugin-custom-validation",
"version": "0.0.0-development",
"private": true,
"description": "",
"keywords": [],
"homepage": "https://github.com/RebeccaStevens/typedoc-plugin-require-tags#readme",
"keywords": [
"typedoc-plugin"
],
"homepage": "https://github.com/RebeccaStevens/typedoc-plugin-custom-validation#readme",
"bugs": {
"url": "https://github.com/RebeccaStevens/typedoc-plugin-require-tags/issues"
"url": "https://github.com/RebeccaStevens/typedoc-plugin-custom-validation/issues"
},
"repository": {
"type": "git",
"url": "git+https://github.com/RebeccaStevens/typedoc-plugin-require-tags"
"url": "git+https://github.com/RebeccaStevens/typedoc-plugin-custom-validation"
},
"license": "BSD-3-Clause",
"author": {
Expand Down Expand Up @@ -98,7 +100,11 @@
"rollup-plugin-dts": "5.2.0",
"semantic-release": "20.1.0",
"ts-node": "10.9.1",
"typedoc": "0.23.26",
"typescript": "4.9.5"
},
"peerDependencies": {
"typedoc": "^0.23.26"
},
"packageManager": "pnpm@7.27.0"
}
48 changes: 48 additions & 0 deletions pnpm-lock.yaml

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

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

// Write me
export type CustomValidationOptions = {
byKind: ByKindEntry[];
};

export type ByKindEntry = {
kinds: keyof typeof ReflectionKind | Array<keyof typeof ReflectionKind>;
tags?: string | string[];
summary?: boolean;
};

export function load(app: Readonly<Application>) {
app.options.addDeclaration({
name: "customValidation",
help: "The configuration object of the require-tags plugin.",
type: ParameterType.Object,
});

app.on(
Application.EVENT_VALIDATE_PROJECT,
(project: Readonly<ProjectReflection>) => {
const customValidationOptions = app.options.getValue(
"customValidation"
) as CustomValidationOptions;

let m_kinds = customValidationOptions.byKind
.flatMap((by) => by.kinds)
.map((kind) => ReflectionKind[kind])
.reduce((p, c) => p | c);

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;
}

type Requirements = { tags: string[]; summary: boolean };

const requirementsByKind = new Map<number, Requirements>(
customValidationOptions.byKind.flatMap(({ kinds, tags, summary }) =>
(Array.isArray(kinds) ? kinds : [kinds]).map(
(kindString): [number, Requirements] => {
const kind = ReflectionKind[kindString];
const realKind =
reflectionKindReplacements.find(
([oldKind]) => (oldKind & kind) !== 0
)?.[1] ?? kind;

return [
realKind,
{
tags:
tags === undefined
? []
: Array.isArray(tags)
? tags
: [tags],
summary: summary ?? false,
},
];
}
)
)
);

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() || reflection.comment!.isEmpty()) {
app.logger.warn(
`${reflection.getFriendlyFullName()} does not have any documentation.`
);
continue;
}

const requirements = requirementsByKind.get(reflection.kind);
if (requirements !== undefined) {
if (
requirements.summary &&
reflection.comment!.summary.length === 0
) {
app.logger.warn(
`${reflection.getFriendlyFullName()} does not have a summary.`
);
}

for (const tagName of requirements.tags) {
const tag: `@${string}` = tagName.startsWith("@")
? (tagName as `@${string}`)
: `@${tagName}`;

if (reflection.comment!.getTags(tag).length === 0) {
app.logger.warn(
`${reflection.getFriendlyFullName()} does not have any ${tag} tags.`
);
}
}
}
}
}
);
}

0 comments on commit 8806846

Please sign in to comment.