diff --git a/cli/package.json b/cli/package.json index c4cc021e29..a1928ff2ae 100644 --- a/cli/package.json +++ b/cli/package.json @@ -26,7 +26,8 @@ "test:genKeypair": "ts-mocha --exit tests/unit/genKeyPair.test.ts", "test:timeTravel": "ts-mocha --exit tests/unit/timeTravel.test.ts", "test:fundWallet": "ts-mocha --exit tests/unit/fundWallet.test.ts", - "test:utils": "ts-mocha --exit tests/unit/utils.test.ts" + "test:utils": "ts-mocha --exit tests/unit/utils.test.ts", + "typedoc": "typedoc --plugin typedoc-plugin-markdown --options ./typedoc.json" }, "dependencies": { "@commander-js/extra-typings": "^11.1.0", diff --git a/cli/typedoc.json b/cli/typedoc.json new file mode 100644 index 0000000000..bd099a031f --- /dev/null +++ b/cli/typedoc.json @@ -0,0 +1,5 @@ +{ + "extends": ["../typedoc.base.json"], + "entryPoints": ["ts/index.ts"], + "out": "../website/typedoc/cli" +} diff --git a/core/README.md b/core/README.md index 6104d1c9e3..2db5c7ee71 100644 --- a/core/README.md +++ b/core/README.md @@ -15,7 +15,7 @@ contracts in discrete components which are easy to test. To this end, this submodule exposes a `MaciState` class and a `Poll` class. Developers should instantiate objects from these classes to test MACI. For -instance, [`MACI.test.ts`](`../contracts/ts/__tests__/MACI.test.ts`) creates a +instance, [`MACI.test.ts`](https://github.com/privacy-scaling-explorations/maci/blob/dev/contracts/tests/MACI.test.ts) creates a `MaciState` object and every time it interacts with the MACI smart contract, it mirrors said interaction on the `MaciState` and `Poll`. As such, the developer can then use their helper functions like `maciState.signUp()`, @@ -35,7 +35,7 @@ call `maciState.signUp()` as well, so that the off-chain representation of MACI is kept up to date. In production, `genMaciStateFromContract()` in -[`genMaciState.ts`](`contracts/ts/genMaciState.ts`) uses this function when it +[`genMaciState.ts`](https://github.com/privacy-scaling-explorations/maci/blob/dev/contracts/ts/genMaciState.ts) uses this function when it scans a MACI contract's event log for signups, so as to bring its `MaciState` instance up to date. diff --git a/core/package.json b/core/package.json index fcbb2ec1d5..24ae16c714 100644 --- a/core/package.json +++ b/core/package.json @@ -18,7 +18,8 @@ "test:e2e": "ts-mocha --exit ts/__tests__/e2e.test.ts", "test:utils": "ts-mocha --exit ts/__tests__/utils.test.ts", "test:poll": "ts-mocha --exit ts/__tests__/Poll.test.ts", - "test": "nyc ts-mocha --exit ts/__tests__/*.test.ts" + "test": "nyc ts-mocha --exit ts/__tests__/*.test.ts", + "typedoc": "typedoc --plugin typedoc-plugin-markdown --options ./typedoc.json" }, "dependencies": { "maci-crypto": "^1.1.2", diff --git a/core/typedoc.json b/core/typedoc.json new file mode 100644 index 0000000000..438d9b71d5 --- /dev/null +++ b/core/typedoc.json @@ -0,0 +1,5 @@ +{ + "extends": ["../typedoc.base.json"], + "entryPoints": ["ts/index.ts"], + "out": "../website/typedoc/core" +} diff --git a/crypto/package.json b/crypto/package.json index 45baee78cf..1ed622f692 100644 --- a/crypto/package.json +++ b/crypto/package.json @@ -17,7 +17,8 @@ "test:crypto": "ts-mocha --exit ts/__tests__/Crypto.test.ts", "test:accQueue": "ts-mocha --exit ts/__tests__/AccQueue.test.ts", "test:utils": "ts-mocha --exit ts/__tests__/Utils.test.ts", - "test:imt": "ts-mocha --exit ts/__tests__/IMT.test.ts" + "test:imt": "ts-mocha --exit ts/__tests__/IMT.test.ts", + "typedoc": "typedoc --plugin typedoc-plugin-markdown --options ./typedoc.json" }, "dependencies": { "@zk-kit/baby-jubjub": "^0.1.1", diff --git a/crypto/typedoc.json b/crypto/typedoc.json new file mode 100644 index 0000000000..22bf7e1f80 --- /dev/null +++ b/crypto/typedoc.json @@ -0,0 +1,5 @@ +{ + "extends": ["../typedoc.base.json"], + "entryPoints": ["ts/index.ts"], + "out": "../website/typedoc/crypto" +} diff --git a/domainobjs/package.json b/domainobjs/package.json index 1edd5c5cc4..0df08d8d72 100644 --- a/domainobjs/package.json +++ b/domainobjs/package.json @@ -12,7 +12,8 @@ "watch": "tsc --watch", "build": "tsc -p tsconfig.build.json", "types": "tsc -p tsconfig.json --noEmit", - "test": "nyc ts-mocha --exit ts/__tests__/**.test.ts" + "test": "nyc ts-mocha --exit ts/__tests__/**.test.ts", + "typedoc": "typedoc --plugin typedoc-plugin-markdown --options ./typedoc.json" }, "devDependencies": { "@types/chai": "^4.3.11", diff --git a/domainobjs/typedoc.json b/domainobjs/typedoc.json new file mode 100644 index 0000000000..76a11e33bd --- /dev/null +++ b/domainobjs/typedoc.json @@ -0,0 +1,5 @@ +{ + "extends": ["../typedoc.base.json"], + "entryPoints": ["ts/index.ts"], + "out": "../website/typedoc/domainobjs" +} diff --git a/package.json b/package.json index 8b77e500f6..b03c593fa6 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "test:integration": "lerna run test --scope \"maci-integrationtests\"", "test": "lerna run test --ignore maci-integrationtests --ignore maci-cli", "types": "lerna run types", - "typedoc": "typedoc --plugin typedoc-plugin-markdown --options typedoc.json", + "typedoc": "lerna run typedoc", "prepare": "is-ci || husky install" }, "author": "PSE", diff --git a/typedoc.base.json b/typedoc.base.json new file mode 100644 index 0000000000..d798bf9033 --- /dev/null +++ b/typedoc.base.json @@ -0,0 +1,9 @@ +{ + "name": "Minimal Anti Collusion Infrastructure (MACI)", + "$schema": "https://typedoc.org/schema.json", + "includeVersion": true, + "navigation": { + "includeFolders": false + }, + "exclude": ["**/emitter", "**/eslint-config-custom", "**/tsconfig"] +} diff --git a/typedoc.json b/typedoc.json deleted file mode 100644 index f7515801f6..0000000000 --- a/typedoc.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "entryPoints": ["./crypto/ts/index.ts", "./core/ts/index.ts", "./domainobjs/ts/index.ts", "./cli/ts/index.ts"], - "name": "Minimal Anti Collusion Infrastructure (MACI)", - "entryPointStrategy": "resolve", - "exclude": [ - "**/emitter", - "**/eslint-config-custom", - "**/tsconfig", - "**/artifacts", - "./contracts/**/*", - "./circuits/**/*", - "./integrationTests/**/*" - ], - "out": "./website/typedoc/" -} diff --git a/website/src/scripts/setupSolidityDocs.ts b/website/src/scripts/setupSolidityDocs.ts index 8e240ef4c0..be7e3bca94 100644 --- a/website/src/scripts/setupSolidityDocs.ts +++ b/website/src/scripts/setupSolidityDocs.ts @@ -1,7 +1,7 @@ import fs from "fs"; import path from "path"; -import { copyDirectory } from "./utils"; +import { copyDirectory, insertIndexPage } from "./utils"; // where to move the solidity doc files over const solidityDocDir = path.resolve(__dirname, "../../versioned_docs/version-v1.x/solidity-docs"); @@ -45,3 +45,5 @@ function updateHeadings(dir: string) { copyDirectory(sourceDir, solidityDocDir); // update the headings updateHeadings(solidityDocDir); +// insert index page +insertIndexPage(solidityDocDir, { title: "Solidity Docs", label: "Solidity Docs" }); diff --git a/website/src/scripts/setupTypedoc.ts b/website/src/scripts/setupTypedoc.ts index c2c243c963..a289959ae4 100644 --- a/website/src/scripts/setupTypedoc.ts +++ b/website/src/scripts/setupTypedoc.ts @@ -1,45 +1,72 @@ import fs from "fs"; import path from "path"; -import { copyDirectory } from "./utils"; +import { copyDirectory, fitFormat, generateSidebarString, insertIndexPage } from "./utils"; const TYPEDOC_DIR = path.resolve(__dirname, "../../typedoc"); /** - * The Typedoc tool automatically generates related documentation links in each file. The link for the introduction of MACI is initially set to `README.md` of the entire project, but this should be changed to `introduction.md`. Simultaneously, references to `modules.md` should be updated to `index.md` since it is slated to be renamed as Typedoc's homepage. - * @param dirName - the name of the typedoc directory + * A function that remove the auto-genrated navigator + * and the title at the top of the page, + * meanwhile adding sidebar configurations above the content. + * @param file - the file being updated + * @param sidebarInfo - sidebar infos, passed in as a string */ -function updateMentionFiles(dirName: string) { - const dir = path.join(TYPEDOC_DIR, dirName); - const files = fs.readdirSync(dir); - files.forEach((file) => { - const filename = path.join(dir, file); - let content = fs.readFileSync(filename, "utf8"); - content = content.replaceAll("../README.md", "../../introduction.md"); - content = content.replaceAll("../modules.md", "../index.md"); - fs.writeFileSync(filename, content); - }); -} +function updateMdFiles(file: string, sidebarInfo: string) { + const content = fs.readFileSync(file).toString().split("\n"); -// Remove the README.md file if exists -const readmeFile = path.join(TYPEDOC_DIR, "README.md"); -if (fs.existsSync(readmeFile)) { - fs.unlinkSync(readmeFile); -} + if (content.length > 3) { + content.shift(); + content.shift(); + content.shift(); + } -// Rename modules.md to index.md, and change the README.md mention to ../introduction.md -const modulesFile = path.join(TYPEDOC_DIR, "modules.md"); -if (fs.existsSync(modulesFile)) { - let content = fs.readFileSync(modulesFile, "utf8"); - content = content.replaceAll("README.md", "../introduction.md"); - fs.writeFileSync(modulesFile, content); - fs.renameSync(modulesFile, path.join(TYPEDOC_DIR, "index.md")); + const writtenContent = content.join("\n").replaceAll("README.md", "index.md"); + fs.writeFileSync(file, `${sidebarInfo}\n${writtenContent}`); } -// Change all ../README.md mention to ../../introduction.md, and change all ../modeuls.md mention to ../index.md -updateMentionFiles("classes"); -updateMentionFiles("interfaces"); -updateMentionFiles("modules"); +// read all dir in typedoc/ -> rename README.md as index.md -> remove upper navigations +const directories = fs.readdirSync(TYPEDOC_DIR); +directories.forEach((dir) => { + const dirname = path.resolve(TYPEDOC_DIR, dir); + const label = fitFormat(dir); + + // only do things if it's a directory + if (fs.statSync(dirname).isDirectory()) { + const readmeFile = path.join(dirname, "README.md"); + + if (fs.existsSync(readmeFile)) { + updateMdFiles(readmeFile, generateSidebarString({ title: label, label })); + fs.renameSync(readmeFile, path.join(dirname, "index.md")); + } + + // remove the first two lines of navigator + const modulesFile = path.join(dirname, "modules.md"); + + if (fs.existsSync(modulesFile)) { + updateMdFiles(modulesFile, generateSidebarString({ title: `${label} Module`, label: "module", position: 1 })); + } + + const innerDirs = fs.readdirSync(dirname); + innerDirs.forEach((innerDir) => { + const innerDirname = path.join(dirname, innerDir); + + if (fs.statSync(innerDirname).isDirectory()) { + const innerFiles = fs.readdirSync(innerDirname); + innerFiles.forEach((innerFile) => { + const innerLabel = innerFile.split(".")[0]; + updateMdFiles( + path.join(innerDirname, innerFile), + generateSidebarString({ title: innerLabel, label: innerLabel }), + ); + }); + } + }); + } +}); + +// insert index page +insertIndexPage(TYPEDOC_DIR, { title: "Typedoc", label: "Typedoc" }); // find the target moving directory const versionFile = path.resolve(__dirname, "../../versions.json"); diff --git a/website/src/scripts/utils.ts b/website/src/scripts/utils.ts index 732ac63021..c938e4cbd3 100644 --- a/website/src/scripts/utils.ts +++ b/website/src/scripts/utils.ts @@ -28,3 +28,60 @@ export function copyDirectory(source: string, target: string): void { } }); } + +/** + * A function that forces the first letter to be capital, + * while the rest of the string must be lower case. + * @param str - the string being transformed + */ +export function fitFormat(str: string): string { + return `${str[0].toUpperCase()}${str.slice(1, str.length).toLowerCase()}`; +} + +/** + * Sidebar Parameters + */ +interface SidebarProps { + title?: string; + description?: string; + label?: string; + position?: number; +} + +/** + * A function that forces the first letter to be capital, + * while the rest of the string must be lower case. + * @param sidebarProps - including title, description, label, and position + */ +export function generateSidebarString({ title, description, label, position }: SidebarProps): string { + let ret = "---\n"; + + if (title) { + ret = `${ret}title: ${title}\n`; + } + + if (description) { + ret = `${ret}description: ${description}\n`; + } + + if (label) { + ret = `${ret}sidebar_label: ${label}\n`; + } + + if (position) { + ret = `${ret}sidebar_position: ${position}\n`; + } + + ret = `${ret}---\n`; + + return ret; +} + +/** + * A function that insert a index page + * @param dir - the directory to insert an index page + * @param sidebarProps - including title, description, label, and position + */ +export function insertIndexPage(dir: string, { title, description, label, position }: SidebarProps): void { + fs.writeFileSync(`${dir}/index.md`, generateSidebarString({ title, description, label, position })); +}