Skip to content

Commit

Permalink
Merge branch 'bugfix/GH-17-project-documents-not-working'
Browse files Browse the repository at this point in the history
  • Loading branch information
krisztianb committed Sep 22, 2024
2 parents 76384ce + 6532dc2 commit c8b4eeb
Show file tree
Hide file tree
Showing 36 changed files with 1,572 additions and 451 deletions.
8 changes: 7 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [6.0.1] - 2024-09-22
### Fixed
- Project documentations (introduced in TypeDoc 0.26) were incorrectly handled and removed by the plugin.
- Merging only happened at the root level and didn't take into account that TypeDoc creates parent modules for projects within monorepos.

## [6.0.0] - 2024-06-30
### BREAKING CHANGES
- Support changed to TypeDoc version 0.26.x due to a breaking change in TypeDoc's API.
Expand Down Expand Up @@ -78,7 +83,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

First release

[unreleased]: https://github.com/krisztianb/typedoc-plugin-merge-modules/compare/v6.0.0...HEAD
[unreleased]: https://github.com/krisztianb/typedoc-plugin-merge-modules/compare/v6.0.1...HEAD
[6.0.1]: https://github.com/krisztianb/typedoc-plugin-merge-modules/releases/tag/v6.0.1
[6.0.0]: https://github.com/krisztianb/typedoc-plugin-merge-modules/releases/tag/v6.0.0
[5.1.0]: https://github.com/krisztianb/typedoc-plugin-merge-modules/releases/tag/v5.1.0
[5.0.1]: https://github.com/krisztianb/typedoc-plugin-merge-modules/releases/tag/v5.0.1
Expand Down
1,678 changes: 1,325 additions & 353 deletions package-lock.json

Large diffs are not rendered by default.

13 changes: 6 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "typedoc-plugin-merge-modules",
"version": "6.0.0",
"version": "6.0.1",
"description": "Plugin for TypeDoc that merges the content of modules.",
"author": {
"name": "Krisztián Balla",
Expand All @@ -12,19 +12,18 @@
"typedocplugin"
],
"devDependencies": {
"@types/mocha": "10.0.7",
"@types/node": "20.14.9",
"@typescript-eslint/eslint-plugin": "7.14.1",
"@typescript-eslint/parser": "7.14.1",
"cypress": "12.13.0",
"cypress": "13.14.2",
"eslint": "8.56.0",
"eslint-plugin-jsdoc": "48.5.0",
"eslint-plugin-ordered-imports": "0.6.0",
"eslint-plugin-unicorn": "54.0.0",
"prettier": "3.3.2",
"rimraf": "5.0.7",
"typedoc": "0.26.3",
"typescript": "5.5.2"
"prettier": "3.3.3",
"rimraf": "6.0.1",
"typedoc": "0.26.7",
"typescript": "5.5.4"
},
"peerDependencies": {
"typedoc": "0.26.x"
Expand Down
6 changes: 3 additions & 3 deletions src/merger/module_merger.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/** @module merger */
import { DeclarationReflection, ProjectReflection, ReflectionKind } from "typedoc";
import { DeclarationReflection, ProjectReflection } from "typedoc";
import { getModulesFrom } from "../utils";
import { ModuleBundle } from "./module_bundle";

/**
Expand Down Expand Up @@ -40,7 +40,7 @@ export class ModuleMerger {
* @returns The collection of module bundles.
*/
protected createModuleBundles(): ModuleBundle[] {
const modules = (this.project.children ?? []).filter((c) => c.kindOf(ReflectionKind.Module));
const modules = getModulesFrom(this.project);
const moduleBundleMap = new Map<string, ModuleBundle>();

for (const module of modules) {
Expand Down
30 changes: 18 additions & 12 deletions src/merger/project_merger.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
/** @module merger */
import { DeclarationReflection, DocumentReflection, ProjectReflection, ReflectionKind } from "typedoc";
import {
addDeclarationReflectionToTarget,
addDocumentReflectionToTarget,
getModulesFrom,
removeDeclarationReflectionFromModule,
removeDocumentReflectionFromModule,
} from "../utils";
Expand All @@ -26,18 +26,22 @@ export class ProjectMerger {
* Performs the merging routine.
*/
public execute(): void {
const modules = (this.project.children ?? []).filter((c) => c.kindOf(ReflectionKind.Module));
// In monorepo project each project is also a module => Recursively collect all modules
const allModules = getModulesFrom(this.project);

if (modules.length > 0) {
this.clearProject();
if (allModules.length > 0) {
this.removeModulesFromProject();

for (const mod of modules) {
for (const module of allModules) {
// Here we create a copy because the next loop modifies the collection
const reflections = [...(mod.childrenIncludingDocuments ?? [])];
const reflections = [...(module.childrenIncludingDocuments ?? [])];

for (const ref of reflections) {
// Drop aliases (= ReflectionKind.Reference)
if (ref instanceof DeclarationReflection && !ref.kindOf(ReflectionKind.Reference)) {
// Drop aliases (= ReflectionKind.Reference) and modules
if (
ref instanceof DeclarationReflection &&
!ref.kindOf([ReflectionKind.Reference, ReflectionKind.Module])
) {
this.moveDeclarationReflectionToProject(ref);
} else if (ref instanceof DocumentReflection) {
this.moveDocumentReflectionFromToProject(ref);
Expand All @@ -48,13 +52,15 @@ export class ProjectMerger {
}

/**
* Removes all children and documents from the project reflection.
* Removes all modules from the project reflection. Doesn't touch the project documents.
*/
private clearProject(): void {
private removeModulesFromProject(): void {
this.project.children = [];
this.project.documents = [];
this.project.childrenIncludingDocuments = [];
this.project.children.forEach((child) => this.project.removeReflection(child));

// keep project documents that are included with the TypeDoc config parameter "projectDocuments"
this.project.childrenIncludingDocuments =
this.project.childrenIncludingDocuments?.filter((item) => item instanceof DocumentReflection) ?? [];
}

/**
Expand Down
18 changes: 17 additions & 1 deletion src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Context, DeclarationReflection, DocumentReflection, ProjectReflection } from "typedoc";
import { Context, DeclarationReflection, DocumentReflection, ProjectReflection, ReflectionKind } from "typedoc";
import * as ts from "typescript";

/**
Expand Down Expand Up @@ -124,3 +124,19 @@ export function removeDocumentReflectionFromModule(ref: DocumentReflection): voi
module.childrenIncludingDocuments?.splice(indexInChildrenIncludingDocuments, 1);
}
}

/**
* Returns the modules within the given module parent. Searches recursively.
* @param moduleParent The element in which to search for modules.
* @returns The modules within the given module parent.
*/
export function getModulesFrom(moduleParent: ProjectReflection | DeclarationReflection): DeclarationReflection[] {
const modules = (moduleParent.children ?? []).filter((c) => c.kindOf(ReflectionKind.Module));

for (const mod of modules) {
const subModules = getModulesFrom(mod);
modules.push(...subModules);
}

return modules;
}
9 changes: 9 additions & 0 deletions test/default-export-rename-off/typedoc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"$schema": "https://typedoc.org/schema.json",
"name": "Project Default-Export-Rename-Off",
"entryPoints": ["input/*.ts"],
"entryPointStrategy": "expand",
"out": "output",
"plugin": ["typedoc-plugin-merge-modules"],
"mergeModulesRenameDefaults": false
}
9 changes: 9 additions & 0 deletions test/default-export-rename-on/typedoc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"$schema": "https://typedoc.org/schema.json",
"name": "Project Default-Export-Rename-On",
"entryPoints": ["input/*.ts"],
"entryPointStrategy": "expand",
"out": "output",
"plugin": ["typedoc-plugin-merge-modules"],
"mergeModulesRenameDefaults": true
}
1 change: 1 addition & 0 deletions test/merge-module-category/input/project-documents/doc1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# This is the project documentation file doc1.md
4 changes: 4 additions & 0 deletions test/merge-module-category/test.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ describe("index.html", () => {
cy.get("nav").find("a[href='./modules/merged-1.html']"); // for C
cy.get("nav").find("a[href='./modules/merged-2.html']"); // for D
});

it("contains a link to the project documentation", () => {
cy.get("nav").find("a[href='./documents/doc1.html']");
});
});

describe("modules/e.html", () => {
Expand Down
10 changes: 10 additions & 0 deletions test/merge-module-category/typedoc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"$schema": "https://typedoc.org/schema.json",
"name": "Project Merge-Module-Category",
"entryPoints": ["input/*.ts"],
"entryPointStrategy": "expand",
"projectDocuments": ["input/project-documents/*.md"],
"out": "output",
"plugin": ["typedoc-plugin-merge-modules"],
"mergeModulesMergeMode": "module-category"
}
1 change: 1 addition & 0 deletions test/merge-module-monorepo/input/project1/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
/** @module merged */
export { A } from "./a";
export { B } from "./b";
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# This is the project documentation file doc1.md
3 changes: 2 additions & 1 deletion test/merge-module-monorepo/input/project1/typedoc.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"$schema": "https://typedoc.org/schema.json",
"name": "Project 1",
"entryPoints": ["index.ts"]
"entryPoints": ["index.ts"],
"projectDocuments": ["project-documents/*.md"]
}
4 changes: 4 additions & 0 deletions test/merge-module-monorepo/input/project2/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
/**
* @module merged
* @mergeTarget
*/
export { C } from "./c";
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# This is the project documentation file doc2.md
5 changes: 3 additions & 2 deletions test/merge-module-monorepo/input/project2/typedoc.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"$schema": "https://typedoc.org/schema.json",
"name": "Project 1",
"entryPoints": ["index.ts"]
"name": "Project 2",
"entryPoints": ["index.ts"],
"projectDocuments": ["project-documents/*.md"]
}
46 changes: 31 additions & 15 deletions test/merge-module-monorepo/test.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,47 @@ describe("index.html", () => {
cy.visit("./merge-module-monorepo/output/index.html");
});

it("contains no module links for a, b and c", () => {
cy.get("nav").find("a[href='./modules/a.html']").should("not.exist");
cy.get("nav").find("a[href='./modules/b.html']").should("not.exist");
cy.get("nav").find("a[href='./modules/c.html']").should("not.exist");
it("contains no module links for the 'index' modules", () => {
cy.get("nav").find("a[href='./modules/Project_1.index.html']").should("not.exist");
cy.get("nav").find("a[href='./modules/Project_2.index.html']").should("not.exist");
});

it("contains a module link for 'Project 1'", () => {
cy.get("nav").find("a[href='./modules/Project_1.html']");
});
});

describe("modules/Project_1.html", () => {
beforeEach(() => {
cy.visit("./merge-module-monorepo/output/modules/Project_1.html");
it("contains a link to the project documentation of 'Project 1'", () => {
cy.get("nav").find("a[href='./documents/Project_1.doc1.html']");
});

it("contains no module link for the 'merged' module within 'Project 1'", () => {
cy.get("nav").find("a[href='./modules/Project_1.merged.html']").should("not.exist");
});

it("contains a module link for 'Project 2'", () => {
cy.get("nav").find("a[href='./modules/Project_2.html']");
});

it("contains sub links to the classes A, B and C", () => {
cy.get("nav").find("a[href='../classes/Project_1.A.html']");
cy.get("nav").find("a[href='../classes/Project_1.B.html']");
cy.get("nav").find("a[href='../classes/Project_1.C.html']");
it("contains a link to the project documentation of 'Project 2'", () => {
cy.get("nav").find("a[href='./documents/Project_2.doc2.html']");
});

it("contains links for the 'merged' module within 'Project 2'", () => {
cy.get("nav").find("a[href='./modules/Project_2.merged.html']");
cy.get("nav").find("a[href='./classes/Project_2.merged.A.html']");
cy.get("nav").find("a[href='./classes/Project_2.merged.B.html']");
cy.get("nav").find("a[href='./classes/Project_2.merged.C.html']");
});
});

describe("modules/Project_2.merged.html", () => {
beforeEach(() => {
cy.visit("./merge-module-monorepo/output/modules/Project_2.merged.html");
});

it("contains index links to the classes A, B and C", () => {
cy.get(".col-content .tsd-index-list").find("a[href='../classes/Project_1.A.html']");
cy.get(".col-content .tsd-index-list").find("a[href='../classes/Project_1.B.html']");
cy.get(".col-content .tsd-index-list").find("a[href='../classes/Project_1.C.html']");
cy.get(".col-content .tsd-index-list").find("a[href='../classes/Project_2.merged.A.html']");
cy.get(".col-content .tsd-index-list").find("a[href='../classes/Project_2.merged.B.html']");
cy.get(".col-content .tsd-index-list").find("a[href='../classes/Project_2.merged.C.html']");
});
});
9 changes: 9 additions & 0 deletions test/merge-module-monorepo/typedoc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"$schema": "https://typedoc.org/schema.json",
"name": "Project Merge-Module-Monorepo",
"entryPoints": ["input/project1", "input/project2"],
"entryPointStrategy": "packages",
"out": "output",
"plugin": ["typedoc-plugin-merge-modules"],
"mergeModulesMergeMode": "module"
}
1 change: 1 addition & 0 deletions test/merge-module/input/project-documents/doc1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# This is the project documentation file doc1.md
4 changes: 4 additions & 0 deletions test/merge-module/test.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ describe("index.html", () => {
it("contains a merged module link for a and b", () => {
cy.get("nav").find("a[href='./modules/merged.html']");
});

it("contains a link to the project documentation", () => {
cy.get("nav").find("a[href='./documents/doc1.html']");
});
});

describe("modules/c.html", () => {
Expand Down
10 changes: 10 additions & 0 deletions test/merge-module/typedoc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"$schema": "https://typedoc.org/schema.json",
"name": "Project Merge-Module",
"entryPoints": ["input/*.ts"],
"entryPointStrategy": "expand",
"projectDocuments": ["input/project-documents/*.md"],
"out": "output",
"plugin": ["typedoc-plugin-merge-modules"],
"mergeModulesMergeMode": "module"
}
1 change: 1 addition & 0 deletions test/merge-off/input/project-documents/doc1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# This is the project documentation file doc1.md
4 changes: 4 additions & 0 deletions test/merge-off/test.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ describe("index.html", () => {
cy.get("nav").find("a[href='./modules/b.html']");
cy.get("nav").find("a[href='./modules/c.html']");
});

it("contains a link to the project documentation", () => {
cy.get("nav").find("a[href='./documents/doc1.html']");
});
});

describe("modules/a.html", () => {
Expand Down
10 changes: 10 additions & 0 deletions test/merge-off/typedoc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"$schema": "https://typedoc.org/schema.json",
"name": "Project Merge-Off",
"entryPoints": ["input/*.ts"],
"entryPointStrategy": "expand",
"projectDocuments": ["input/project-documents/*.md"],
"out": "output",
"plugin": ["typedoc-plugin-merge-modules"],
"mergeModulesMergeMode": "off"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# This is the project documentation file doc1.md
3 changes: 2 additions & 1 deletion test/merge-project-monorepo/input/project1/typedoc.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"$schema": "https://typedoc.org/schema.json",
"name": "Project 1",
"entryPoints": ["index.ts"]
"entryPoints": ["index.ts"],
"projectDocuments": ["project-documents/*.md"]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# This is the project documentation file doc2.md
3 changes: 2 additions & 1 deletion test/merge-project-monorepo/input/project2/typedoc.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"$schema": "https://typedoc.org/schema.json",
"name": "Project 2",
"entryPoints": ["index.ts"]
"entryPoints": ["index.ts"],
"projectDocuments": ["project-documents/*.md"]
}
5 changes: 5 additions & 0 deletions test/merge-project-monorepo/test.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,9 @@ describe("index.html", () => {
cy.get("nav").find("a[href='./classes/B.html']");
cy.get("nav").find("a[href='./classes/C.html']");
});

it("contains links to the project documentations", () => {
cy.get("nav").find("a[href='./documents/doc1.html']");
cy.get("nav").find("a[href='./documents/doc2.html']");
});
});
9 changes: 9 additions & 0 deletions test/merge-project-monorepo/typedoc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"$schema": "https://typedoc.org/schema.json",
"name": "Project Merge-Project-Monorepo",
"entryPoints": ["input/project1", "input/project2"],
"entryPointStrategy": "packages",
"out": "output",
"plugin": ["typedoc-plugin-merge-modules"],
"mergeModulesMergeMode": "project"
}
1 change: 1 addition & 0 deletions test/merge-project/input/project-documents/doc1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# This is the project documentation file doc1.md
Loading

0 comments on commit c8b4eeb

Please sign in to comment.