docs: create typedoc theme and plugins for references (#5297)
* update typedoc and its plugins * refactor existing typedoc configurations * added new typedoc plugin and themes * added more customization options * added more customization options * refactored doc-utils to a workspace * fix tsconfig * update README files * remove comments * revert type changes * remove dependencies no longer needed * removed modules action
This commit is contained in:
@@ -32,5 +32,10 @@ jobs:
|
||||
with:
|
||||
extension: docs-freshness-check
|
||||
|
||||
- name: Install Workspace dependencies
|
||||
run: yarn install
|
||||
working-directory: docs-utils
|
||||
|
||||
- name: Perform Freshness Check
|
||||
run: yarn check:freshness
|
||||
working-directory: docs-utils/packages/scripts
|
||||
|
||||
@@ -30,11 +30,13 @@ jobs:
|
||||
with:
|
||||
extension: docs-release
|
||||
|
||||
- name: Build Packages
|
||||
run: yarn build
|
||||
- name: Install Workspace dependencies
|
||||
run: yarn install
|
||||
working-directory: docs-utils
|
||||
|
||||
- name: Generate Announcement Bar
|
||||
run: yarn generate:announcement
|
||||
working-directory: docs-utils/packages/scripts
|
||||
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@v4
|
||||
|
||||
@@ -31,8 +31,13 @@ jobs:
|
||||
with:
|
||||
extension: docs-remove-announcement
|
||||
|
||||
- name: Install Workspace dependencies
|
||||
run: yarn install
|
||||
working-directory: docs-utils
|
||||
|
||||
- name: Remove Announcement Bar
|
||||
run: yarn generate:announcement --expire
|
||||
working-directory: docs-utils/packages/scripts
|
||||
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@v4
|
||||
|
||||
@@ -32,6 +32,7 @@ jobs:
|
||||
- name: Install Workspace dependencies
|
||||
working-directory: www
|
||||
run: yarn install
|
||||
|
||||
- name: Build Docusaurus website
|
||||
working-directory: www
|
||||
env:
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
name: Generate API Reference
|
||||
on:
|
||||
workflow_dispatch:
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
jobs:
|
||||
api:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Cancel Previous Runs
|
||||
uses: styfle/cancel-workflow-action@0.11.0
|
||||
with:
|
||||
access_token: ${{ github.token }}
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
token: ${{ secrets.REFERENCE_PAT }}
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup Node.js environment
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: "16.20.2"
|
||||
cache: "yarn"
|
||||
|
||||
- name: Install dependencies
|
||||
uses: ./.github/actions/cache-deps
|
||||
with:
|
||||
extension: reference
|
||||
|
||||
- name: Build Packages
|
||||
run: yarn build
|
||||
|
||||
- name: Generate API Reference
|
||||
run: yarn openapi:generate
|
||||
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@v4
|
||||
with:
|
||||
commit-message: "chore(docs): Generated API Reference"
|
||||
base: "develop"
|
||||
title: "chore(docs): Updated API Reference"
|
||||
labels: "type: chore"
|
||||
add-paths: www/apps/api-reference/specs
|
||||
branch: "chore/generate-api-ref"
|
||||
branch-suffix: "timestamp"
|
||||
@@ -1,47 +0,0 @@
|
||||
name: Generate Entity Reference
|
||||
on:
|
||||
workflow_dispatch:
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
jobs:
|
||||
services:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Cancel Previous Runs
|
||||
uses: styfle/cancel-workflow-action@0.11.0
|
||||
with:
|
||||
access_token: ${{ github.token }}
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup Node.js environment
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: "16.20.2"
|
||||
cache: "yarn"
|
||||
|
||||
- name: Install dependencies
|
||||
uses: ./.github/actions/cache-deps
|
||||
with:
|
||||
extension: reference
|
||||
|
||||
- name: Build Packages
|
||||
run: yarn build
|
||||
|
||||
- name: Generate Entities Reference
|
||||
run: yarn generate:entities
|
||||
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@v4
|
||||
with:
|
||||
commit-message: "chore(docs): Generated Entities Reference (automated)"
|
||||
base: "develop"
|
||||
title: "chore(docs): Generated Entities Reference (automated)"
|
||||
labels: "type: chore"
|
||||
add-paths: www/apps/docs/content/references/entities/**
|
||||
branch: "chore/generate-entities"
|
||||
branch-suffix: "timestamp"
|
||||
@@ -1,47 +0,0 @@
|
||||
name: Generate JS Client Reference
|
||||
on:
|
||||
workflow_dispatch:
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
jobs:
|
||||
services:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Cancel Previous Runs
|
||||
uses: styfle/cancel-workflow-action@0.11.0
|
||||
with:
|
||||
access_token: ${{ github.token }}
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup Node.js environment
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: "16.20.2"
|
||||
cache: "yarn"
|
||||
|
||||
- name: Install dependencies
|
||||
uses: ./.github/actions/cache-deps
|
||||
with:
|
||||
extension: reference
|
||||
|
||||
- name: Build Packages
|
||||
run: yarn build
|
||||
|
||||
- name: Generate Services Reference
|
||||
run: yarn generate:js-client
|
||||
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@v4
|
||||
with:
|
||||
commit-message: "chore(docs): Generated JS Client Reference (automated)"
|
||||
base: "develop"
|
||||
title: "chore(docs): Generated JS Client Reference"
|
||||
labels: "type: chore"
|
||||
add-paths: www/apps/docs/content/references/js-client/**
|
||||
branch: "chore/generate-js-client"
|
||||
branch-suffix: "timestamp"
|
||||
@@ -1,47 +0,0 @@
|
||||
name: Generate Services Reference
|
||||
on:
|
||||
workflow_dispatch:
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
jobs:
|
||||
services:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Cancel Previous Runs
|
||||
uses: styfle/cancel-workflow-action@0.11.0
|
||||
with:
|
||||
access_token: ${{ github.token }}
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup Node.js environment
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: "16.20.2"
|
||||
cache: "yarn"
|
||||
|
||||
- name: Install dependencies
|
||||
uses: ./.github/actions/cache-deps
|
||||
with:
|
||||
extension: reference
|
||||
|
||||
- name: Build Packages
|
||||
run: yarn build
|
||||
|
||||
- name: Generate Services Reference
|
||||
run: yarn generate:services
|
||||
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@v4
|
||||
with:
|
||||
commit-message: "chore(docs): Generated Services Reference (automated)"
|
||||
base: "develop"
|
||||
title: "chore(docs): Generated Services Reference (automated)"
|
||||
labels: "type: chore"
|
||||
add-paths: www/apps/docs/content/references/services/**
|
||||
branch: "chore/generate-services"
|
||||
branch-suffix: "timestamp"
|
||||
@@ -0,0 +1,183 @@
|
||||
name: Generate Documentation Reference
|
||||
on:
|
||||
workflow_dispatch:
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
jobs:
|
||||
services:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Cancel Previous Runs
|
||||
uses: styfle/cancel-workflow-action@0.11.0
|
||||
with:
|
||||
access_token: ${{ github.token }}
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup Node.js environment
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: "16.20.2"
|
||||
cache: "yarn"
|
||||
|
||||
- name: Install dependencies
|
||||
uses: ./.github/actions/cache-deps
|
||||
with:
|
||||
extension: reference
|
||||
|
||||
- name: Build Packages
|
||||
run: yarn build
|
||||
|
||||
- name: Install Workspace dependencies
|
||||
run: yarn install
|
||||
working-directory: docs-utils
|
||||
|
||||
- name: Generate Services Reference
|
||||
run: yarn generate:reference services
|
||||
working-directory: docs-utils/packages/scripts
|
||||
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@v4
|
||||
with:
|
||||
commit-message: "chore(docs): Generated Services Reference (automated)"
|
||||
base: "develop"
|
||||
title: "chore(docs): Generated Services Reference (automated)"
|
||||
labels: "type: chore"
|
||||
add-paths: www/apps/docs/content/references/services/**
|
||||
branch: "chore/generate-services"
|
||||
branch-suffix: "timestamp"
|
||||
api:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Cancel Previous Runs
|
||||
uses: styfle/cancel-workflow-action@0.11.0
|
||||
with:
|
||||
access_token: ${{ github.token }}
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
token: ${{ secrets.REFERENCE_PAT }}
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup Node.js environment
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: "16.20.2"
|
||||
cache: "yarn"
|
||||
|
||||
- name: Install dependencies
|
||||
uses: ./.github/actions/cache-deps
|
||||
with:
|
||||
extension: reference
|
||||
|
||||
- name: Build Packages
|
||||
run: yarn build
|
||||
|
||||
- name: Generate API Reference
|
||||
run: yarn openapi:generate
|
||||
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@v4
|
||||
with:
|
||||
commit-message: "chore(docs): Generated API Reference"
|
||||
base: "develop"
|
||||
title: "chore(docs): Updated API Reference"
|
||||
labels: "type: chore"
|
||||
add-paths: www/apps/api-reference/specs
|
||||
branch: "chore/generate-api-ref"
|
||||
branch-suffix: "timestamp"
|
||||
entities:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Cancel Previous Runs
|
||||
uses: styfle/cancel-workflow-action@0.11.0
|
||||
with:
|
||||
access_token: ${{ github.token }}
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup Node.js environment
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: "16.20.2"
|
||||
cache: "yarn"
|
||||
|
||||
- name: Install dependencies
|
||||
uses: ./.github/actions/cache-deps
|
||||
with:
|
||||
extension: reference
|
||||
|
||||
- name: Build Packages
|
||||
run: yarn build
|
||||
|
||||
- name: Install Workspace dependencies
|
||||
run: yarn install
|
||||
working-directory: docs-utils
|
||||
|
||||
- name: Generate Entities Reference
|
||||
run: yarn generate:references entities
|
||||
working-directory: docs-utils/packages/scripts
|
||||
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@v4
|
||||
with:
|
||||
commit-message: "chore(docs): Generated Entities Reference (automated)"
|
||||
base: "develop"
|
||||
title: "chore(docs): Generated Entities Reference (automated)"
|
||||
labels: "type: chore"
|
||||
add-paths: www/apps/docs/content/references/entities/**
|
||||
branch: "chore/generate-entities"
|
||||
branch-suffix: "timestamp"
|
||||
js-client:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Cancel Previous Runs
|
||||
uses: styfle/cancel-workflow-action@0.11.0
|
||||
with:
|
||||
access_token: ${{ github.token }}
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup Node.js environment
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: "16.20.2"
|
||||
cache: "yarn"
|
||||
|
||||
- name: Install dependencies
|
||||
uses: ./.github/actions/cache-deps
|
||||
with:
|
||||
extension: reference
|
||||
|
||||
- name: Build Packages
|
||||
run: yarn build
|
||||
|
||||
- name: Install Workspace dependencies
|
||||
run: yarn install
|
||||
working-directory: docs-utils
|
||||
|
||||
- name: Generate Services Reference
|
||||
run: yarn generate:references js-client
|
||||
working-directory: docs-utils/packages/scripts
|
||||
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@v4
|
||||
with:
|
||||
commit-message: "chore(docs): Generated JS Client Reference (automated)"
|
||||
base: "develop"
|
||||
title: "chore(docs): Generated JS Client Reference"
|
||||
labels: "type: chore"
|
||||
add-paths: www/apps/docs/content/references/js-client/**
|
||||
branch: "chore/generate-js-client"
|
||||
branch-suffix: "timestamp"
|
||||
@@ -0,0 +1,121 @@
|
||||
const path = require("path")
|
||||
|
||||
module.exports = {
|
||||
root: true,
|
||||
parser: "@babel/eslint-parser",
|
||||
parserOptions: {
|
||||
requireConfigFile: false,
|
||||
ecmaFeatures: {
|
||||
experimentalDecorators: true,
|
||||
},
|
||||
project: true,
|
||||
},
|
||||
plugins: ["prettier"],
|
||||
extends: [
|
||||
"eslint:recommended",
|
||||
"plugin:prettier/recommended",
|
||||
],
|
||||
rules: {
|
||||
curly: ["error", "all"],
|
||||
"new-cap": "off",
|
||||
"require-jsdoc": "off",
|
||||
"no-unused-expressions": "off",
|
||||
"no-unused-vars": "off",
|
||||
camelcase: "off",
|
||||
"no-invalid-this": "off",
|
||||
"max-len": [
|
||||
"error",
|
||||
{
|
||||
code: 80,
|
||||
ignoreStrings: true,
|
||||
ignoreRegExpLiterals: true,
|
||||
ignoreComments: true,
|
||||
ignoreTrailingComments: true,
|
||||
ignoreUrls: true,
|
||||
ignoreTemplateLiterals: true,
|
||||
},
|
||||
],
|
||||
semi: ["error", "never"],
|
||||
quotes: [
|
||||
"error",
|
||||
"double",
|
||||
{
|
||||
allowTemplateLiterals: true,
|
||||
},
|
||||
],
|
||||
"comma-dangle": [
|
||||
"error",
|
||||
{
|
||||
arrays: "always-multiline",
|
||||
objects: "always-multiline",
|
||||
imports: "always-multiline",
|
||||
exports: "always-multiline",
|
||||
functions: "never",
|
||||
},
|
||||
],
|
||||
"object-curly-spacing": ["error", "always"],
|
||||
"arrow-parens": ["error", "always"],
|
||||
"linebreak-style": 0,
|
||||
"no-confusing-arrow": [
|
||||
"error",
|
||||
{
|
||||
allowParens: false,
|
||||
},
|
||||
],
|
||||
"space-before-function-paren": [
|
||||
"error",
|
||||
{
|
||||
anonymous: "always",
|
||||
named: "never",
|
||||
asyncArrow: "always",
|
||||
},
|
||||
],
|
||||
"space-infix-ops": "error",
|
||||
"eol-last": ["error", "always"],
|
||||
},
|
||||
env: {
|
||||
es6: true,
|
||||
node: true,
|
||||
},
|
||||
ignorePatterns: [
|
||||
".eslintrc.js",
|
||||
"dist"
|
||||
],
|
||||
overrides: [
|
||||
{
|
||||
files: ["*.ts", "*.js"],
|
||||
plugins: ["@typescript-eslint/eslint-plugin"],
|
||||
extends: [
|
||||
"plugin:@typescript-eslint/recommended",
|
||||
],
|
||||
parser: "@typescript-eslint/parser",
|
||||
parserOptions: {
|
||||
project: [
|
||||
"./tsconfig.json",
|
||||
"./packages/scripts/tsconfig.json",
|
||||
"./packages/typedoc-config/tsconfig.json",
|
||||
"./packages/typedoc-frontmatter-plugin/tsconfig.json",
|
||||
"./packages/typedoc-modules-plugin/tsconfig.json",
|
||||
"./packages/typedoc-markdown-medusa-plugin/tsconfig.json"
|
||||
]
|
||||
},
|
||||
rules: {
|
||||
"valid-jsdoc": "off",
|
||||
"@typescript-eslint/no-non-null-assertion": "off",
|
||||
"@typescript-eslint/no-floating-promises": "error",
|
||||
"@typescript-eslint/await-thenable": "error",
|
||||
"@typescript-eslint/promise-function-async": "error",
|
||||
"@typescript-eslint/keyword-spacing": "error",
|
||||
"@typescript-eslint/space-before-function-paren": [
|
||||
"error",
|
||||
{
|
||||
anonymous: "always",
|
||||
named: "never",
|
||||
asyncArrow: "always",
|
||||
},
|
||||
],
|
||||
"@typescript-eslint/space-infix-ops": "error",
|
||||
},
|
||||
}
|
||||
],
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"endOfLine": "auto",
|
||||
"semi": false,
|
||||
"singleQuote": false,
|
||||
"tabWidth": 2,
|
||||
"trailingComma": "es5",
|
||||
"arrowParens": "always"
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
nodeLinker: node-modules
|
||||
@@ -0,0 +1,3 @@
|
||||
# Docs Util Workspace
|
||||
|
||||
All utility scripts and plugins used for documentation, such as generating documentation, are placed in this workspace.
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"name": "docs-util",
|
||||
"private": true,
|
||||
"workspaces": [
|
||||
"packages/*"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "turbo run build",
|
||||
"watch": "turbo run watch",
|
||||
"lint": "turbo run lint"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/eslint-parser": "^7.22.15",
|
||||
"@typescript-eslint/eslint-plugin": "^6.7.4",
|
||||
"@typescript-eslint/parser": "^6.7.4",
|
||||
"eslint": "^8.36.0",
|
||||
"eslint-config-prettier": "^9.0.0",
|
||||
"eslint-plugin-prettier": "^5.0.0",
|
||||
"prettier": "^3.0.3",
|
||||
"turbo": "latest"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
import { Octokit } from "@octokit/core"
|
||||
import fs from "fs"
|
||||
import path from "path"
|
||||
|
||||
const shouldExpire = process.argv.indexOf("--expire") !== -1
|
||||
const octokit = new Octokit({
|
||||
auth: process.env.GH_TOKEN,
|
||||
})
|
||||
|
||||
async function main() {
|
||||
let announcement = {}
|
||||
|
||||
if (shouldExpire) {
|
||||
//check if the file was last updated 6 days ago
|
||||
try {
|
||||
const commitResponse = await octokit.request(
|
||||
"GET /repos/{owner}/{repo}/commits",
|
||||
{
|
||||
owner: "medusajs",
|
||||
repo: "medusa",
|
||||
path: path.join("www", "apps", "docs", "announcement.json"),
|
||||
per_page: 1,
|
||||
}
|
||||
)
|
||||
|
||||
if (
|
||||
commitResponse.data.length &&
|
||||
commitResponse.data[0].commit.committer?.date &&
|
||||
dateDiffInDays(
|
||||
new Date(commitResponse.data[0].commit.committer.date),
|
||||
new Date()
|
||||
) < 6
|
||||
) {
|
||||
console.log("File was edited less than 6 days ago. Expiry canceled.")
|
||||
return
|
||||
}
|
||||
} catch (e) {
|
||||
//continue as if file doesn't exist
|
||||
}
|
||||
} else {
|
||||
//retrieve the latest release
|
||||
const response = await octokit.request(
|
||||
"GET /repos/{owner}/{repo}/releases/latest",
|
||||
{
|
||||
owner: "medusajs",
|
||||
repo: "medusa",
|
||||
}
|
||||
)
|
||||
|
||||
const version = response.data.tag_name
|
||||
|
||||
//add new announcement
|
||||
announcement = {
|
||||
id: response.data.html_url,
|
||||
content: `${version} is out`,
|
||||
isCloseable: true,
|
||||
}
|
||||
}
|
||||
|
||||
//write new config file
|
||||
fs.writeFileSync(
|
||||
path.join(
|
||||
__dirname,
|
||||
"..",
|
||||
"..",
|
||||
"..",
|
||||
"www",
|
||||
"apps",
|
||||
"docs",
|
||||
"announcement.json"
|
||||
),
|
||||
JSON.stringify(announcement)
|
||||
)
|
||||
console.log(`Announcement Bar has been ${shouldExpire ? "removed" : "added"}`)
|
||||
}
|
||||
|
||||
const _MS_PER_DAY = 1000 * 60 * 60 * 24
|
||||
|
||||
// a and b are javascript Date objects
|
||||
function dateDiffInDays(a: Date, b: Date) {
|
||||
// Discard the time and time-zone information.
|
||||
const utc1 = Date.UTC(a.getFullYear(), a.getMonth(), a.getDate())
|
||||
const utc2 = Date.UTC(b.getFullYear(), b.getMonth(), b.getDate())
|
||||
|
||||
return Math.floor((utc2 - utc1) / _MS_PER_DAY)
|
||||
}
|
||||
|
||||
void main()
|
||||
@@ -0,0 +1,171 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
import { LinearClient } from "@linear/sdk"
|
||||
import { Octokit } from "@octokit/core"
|
||||
import fs from "fs"
|
||||
import path from "path"
|
||||
|
||||
const octokit = new Octokit({
|
||||
auth: process.env.GH_TOKEN,
|
||||
})
|
||||
|
||||
const linearClient = new LinearClient({
|
||||
apiKey: process.env.LINEAR_API_KEY,
|
||||
})
|
||||
|
||||
const repoPath = path.join(
|
||||
__dirname,
|
||||
"..",
|
||||
"..",
|
||||
"..",
|
||||
"www",
|
||||
"apps",
|
||||
"docs",
|
||||
"content"
|
||||
)
|
||||
let freshnessCheckLabelId = ""
|
||||
let documentationTeamId = ""
|
||||
|
||||
async function scanDirectory(startPath: string) {
|
||||
const files = fs.readdirSync(path.join(startPath), {
|
||||
withFileTypes: true,
|
||||
})
|
||||
|
||||
for (const file of files) {
|
||||
const filePath = path.join(startPath, file.name)
|
||||
if (file.isDirectory()) {
|
||||
//if it's references directory, skip
|
||||
if (file.name !== "references" && file.name !== "upgrade-guides") {
|
||||
await scanDirectory(filePath)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
//check that the file is a markdown file
|
||||
if (file.name.indexOf(".md") === -1 && file.name.indexOf(".mdx") === -1) {
|
||||
continue
|
||||
}
|
||||
|
||||
//if it is a file, check its commits in GitHub
|
||||
const commitResponse = await octokit.request(
|
||||
"GET /repos/{owner}/{repo}/commits",
|
||||
{
|
||||
owner: "medusajs",
|
||||
repo: "medusa",
|
||||
path: filePath,
|
||||
per_page: 1,
|
||||
}
|
||||
)
|
||||
|
||||
if (
|
||||
!commitResponse.data.length ||
|
||||
!commitResponse.data[0].commit.committer?.date
|
||||
) {
|
||||
continue
|
||||
}
|
||||
|
||||
const today = new Date()
|
||||
const lastEditedDate = new Date(
|
||||
commitResponse.data[0].commit.committer.date
|
||||
)
|
||||
const monthsSinceEdited = getMonthDifference(lastEditedDate, today)
|
||||
|
||||
if (monthsSinceEdited > 6) {
|
||||
//file was edited more than 6 months ago.
|
||||
//check if there's an issue created for this file since the commit date
|
||||
const existingIssue = await linearClient.issues({
|
||||
filter: {
|
||||
createdAt: {
|
||||
gte: subtractMonths(monthsSinceEdited - 6, today),
|
||||
},
|
||||
title: {
|
||||
containsIgnoreCase: `Freshness check for ${filePath}`,
|
||||
},
|
||||
labels: {
|
||||
some: {
|
||||
id: {
|
||||
eq: freshnessCheckLabelId,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
first: 1,
|
||||
})
|
||||
|
||||
if (existingIssue.nodes.length) {
|
||||
//an issue has been created for the past 6 months. Don't create an issue for it.
|
||||
continue
|
||||
}
|
||||
|
||||
console.log(`Creating an issue for ${filePath}...`)
|
||||
|
||||
//there are no issues in the past 6 months. Create an issue
|
||||
await linearClient.issueCreate({
|
||||
teamId: documentationTeamId,
|
||||
title: `Freshness check for ${filePath}`,
|
||||
labelIds: [freshnessCheckLabelId],
|
||||
description: `File \`${filePath}\` was last edited on ${lastEditedDate.toDateString()}.`,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function main() {
|
||||
//fetch documentation team ID from linear
|
||||
const documentationTeam = await linearClient.teams({
|
||||
filter: {
|
||||
name: {
|
||||
eqIgnoreCase: "Documentation",
|
||||
},
|
||||
},
|
||||
first: 1,
|
||||
})
|
||||
|
||||
if (!documentationTeam.nodes.length) {
|
||||
console.log("Please add Documentation team in Linear first then try again")
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
documentationTeamId = documentationTeam.nodes[0].id
|
||||
|
||||
//fetch freshness check label ID from linear
|
||||
const freshnessCheckLabel = await linearClient.issueLabels({
|
||||
filter: {
|
||||
name: {
|
||||
eqIgnoreCase: "type: freshness-check",
|
||||
},
|
||||
team: {
|
||||
id: {
|
||||
eq: documentationTeamId,
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
if (!freshnessCheckLabel.nodes.length) {
|
||||
console.log(
|
||||
"Please add freshness check label in Linear under the documentation team first then try again"
|
||||
)
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
freshnessCheckLabelId = freshnessCheckLabel.nodes[0].id
|
||||
|
||||
await scanDirectory(repoPath)
|
||||
}
|
||||
|
||||
function getMonthDifference(startDate: Date, endDate: Date) {
|
||||
return (
|
||||
endDate.getMonth() -
|
||||
startDate.getMonth() +
|
||||
12 * (endDate.getFullYear() - startDate.getFullYear())
|
||||
)
|
||||
}
|
||||
|
||||
function subtractMonths(numOfMonths: number, date = new Date()) {
|
||||
date.setMonth(date.getMonth() - numOfMonths)
|
||||
|
||||
return date
|
||||
}
|
||||
|
||||
void main()
|
||||
@@ -0,0 +1,25 @@
|
||||
#!/usr/bin/env node
|
||||
import path from "path"
|
||||
import fs from "fs"
|
||||
import { exec } from "child_process"
|
||||
|
||||
const referenceNames = process.argv.slice(2)
|
||||
referenceNames.forEach((names) => {
|
||||
const configPathName = path.join(
|
||||
__dirname,
|
||||
"..",
|
||||
"typedoc-config",
|
||||
`${names}.js`
|
||||
)
|
||||
|
||||
// check if the config file exists
|
||||
if (!fs.existsSync(configPathName)) {
|
||||
throw new Error(
|
||||
`Config file for ${names} doesn't exist. Make sure to create it in ${configPathName}`
|
||||
)
|
||||
}
|
||||
|
||||
const typedocProcess = exec(`typedoc --options ${configPathName}`)
|
||||
typedocProcess.stdout?.pipe(process.stdout)
|
||||
typedocProcess.stderr?.pipe(process.stdout)
|
||||
})
|
||||
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"name": "scripts",
|
||||
"private": true,
|
||||
"license": "MIT",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"scripts": {
|
||||
"generate:announcement": "ts-node ./doc-change-release.ts",
|
||||
"generate:reference": "ts-node ./generate-reference.ts",
|
||||
"check:freshness": "ts-node ./freshness-check.ts"
|
||||
},
|
||||
"version": "0.0.0",
|
||||
"dependencies": {
|
||||
"@linear/sdk": "^1.22.0",
|
||||
"@octokit/core": "^4.0.5",
|
||||
"ts-node": "^10.9.1",
|
||||
"typedoc": "0.25.1",
|
||||
"typedoc-monorepo-link-types": "^0.0.2",
|
||||
"typedoc-plugin-frontmatter": "*",
|
||||
"typedoc-plugin-markdown": "3.16.0",
|
||||
"typedoc-plugin-markdown-medusa": "*",
|
||||
"typedoc-plugin-merge-modules": "5.1.0",
|
||||
"typedoc-plugin-modules": "*",
|
||||
"typedoc-plugin-reference-excluder": "1.1.3",
|
||||
"typedoc-plugin-rename-defaults": "^0.6.6"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"extends": "../../tsconfig",
|
||||
"compilerOptions": {
|
||||
"outDir": "./dist"
|
||||
},
|
||||
"include": ["*.ts"]
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
/* eslint-disable @typescript-eslint/no-var-requires */
|
||||
const path = require("path")
|
||||
const globalTypedocOptions = require("./typedoc")
|
||||
|
||||
const pathPrefix = path.join(__dirname, "..", "..")
|
||||
|
||||
module.exports = {
|
||||
...globalTypedocOptions,
|
||||
entryPoints: [path.join(pathPrefix, "packages/medusa/src/models/index.ts")],
|
||||
out: [path.join(pathPrefix, "www/apps/docs/content/references/entities")],
|
||||
tsconfig: path.join(pathPrefix, "packages/medusa/tsconfig.json"),
|
||||
name: "Entities Reference",
|
||||
indexTitle: "Entities Reference",
|
||||
entryDocument: "index.md",
|
||||
hideInPageTOC: true,
|
||||
hideBreadcrumbs: true,
|
||||
plugin: [...globalTypedocOptions.plugin, "typedoc-plugin-frontmatter"],
|
||||
frontmatterData: {
|
||||
displayed_sidebar: "entitiesSidebar",
|
||||
},
|
||||
}
|
||||
@@ -1,11 +1,15 @@
|
||||
/* eslint-disable @typescript-eslint/no-var-requires */
|
||||
const path = require("path")
|
||||
const globalTypedocOptions = require("./typedoc")
|
||||
|
||||
const pathPrefix = path.join(__dirname, "..", "..")
|
||||
|
||||
module.exports = {
|
||||
...globalTypedocOptions,
|
||||
entryPoints: ["packages/medusa-js/src/resources"],
|
||||
entryPoints: [path.join(pathPrefix, "packages/medusa-js/src/resources")],
|
||||
entryPointStrategy: "expand",
|
||||
out: ["www/apps/docs/content/references/js-client"],
|
||||
tsconfig: "packages/medusa-js/tsconfig.json",
|
||||
out: [path.join(pathPrefix, "www/apps/docs/content/references/js-client")],
|
||||
tsconfig: path.join(pathPrefix, "packages/medusa-js/tsconfig.json"),
|
||||
name: "JS Client Reference",
|
||||
indexTitle: "JS Client Reference",
|
||||
entryDocument: "index.md",
|
||||
@@ -15,11 +19,10 @@ module.exports = {
|
||||
...globalTypedocOptions.plugin,
|
||||
"typedoc-plugin-merge-modules",
|
||||
"typedoc-plugin-reference-excluder",
|
||||
"typedoc-monorepo-link-types",
|
||||
"typedoc-frontmatter-plugin",
|
||||
"typedoc-plugin-frontmatter",
|
||||
],
|
||||
exclude: [
|
||||
"packages/medusa-js/src/resources/base.ts",
|
||||
path.join(pathPrefix, "packages/medusa-js/src/resources/base.ts"),
|
||||
"node_modules/**",
|
||||
"packages/**/node_modules",
|
||||
],
|
||||
@@ -0,0 +1,71 @@
|
||||
/* eslint-disable @typescript-eslint/no-var-requires */
|
||||
const path = require("path")
|
||||
const globalTypedocOptions = require("./base")
|
||||
|
||||
const pathPrefix = path.join(__dirname, "..", "..", "..")
|
||||
|
||||
module.exports = ({
|
||||
entryPointPath,
|
||||
outPath,
|
||||
tsconfigPath = "",
|
||||
moduleName = "",
|
||||
documentsToFormat = [],
|
||||
additionalFormatting = {},
|
||||
extraOptions = {},
|
||||
}) => {
|
||||
const formatting = {}
|
||||
documentsToFormat.forEach((document) => {
|
||||
formatting[document] = {
|
||||
reflectionTitle: {
|
||||
kind: false,
|
||||
typeParameters: false,
|
||||
suffix: "Reference",
|
||||
},
|
||||
expandMembers: true,
|
||||
showCommentsAsHeader: true,
|
||||
parameterStyle: "list",
|
||||
useTsLinkResolution: false,
|
||||
showReturnSignature: false,
|
||||
sections: {
|
||||
reflection_typeParameters: false,
|
||||
member_declaration_typeParameters: false,
|
||||
reflection_implements: false,
|
||||
reflection_implementedBy: false,
|
||||
reflection_callable: false,
|
||||
reflection_indexable: false,
|
||||
member_signature_typeParameters: false,
|
||||
member_signature_sources: false,
|
||||
member_signature_title: false,
|
||||
},
|
||||
reflectionGroups: {
|
||||
Constructors: false,
|
||||
Properties: false,
|
||||
},
|
||||
...additionalFormatting,
|
||||
}
|
||||
})
|
||||
return {
|
||||
...globalTypedocOptions,
|
||||
entryPoints: [path.join(pathPrefix, entryPointPath)],
|
||||
out: [path.join(pathPrefix, outPath)],
|
||||
tsconfig: path.join(
|
||||
pathPrefix,
|
||||
tsconfigPath || "packages/types/tsconfig.json"
|
||||
),
|
||||
name: `${moduleName} Reference`,
|
||||
indexTitle: `${moduleName} Reference`,
|
||||
entryDocument: "index.md",
|
||||
entryPointStrategy: "expand",
|
||||
hideInPageTOC: true,
|
||||
hideBreadcrumbs: true,
|
||||
plugin: [
|
||||
"typedoc-plugin-markdown-medusa",
|
||||
"typedoc-plugin-modules",
|
||||
"typedoc-plugin-rename-defaults",
|
||||
"typedoc-plugin-frontmatter",
|
||||
],
|
||||
hideMembersSymbol: true,
|
||||
formatting,
|
||||
...extraOptions,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"name": "typedoc-config",
|
||||
"private": true,
|
||||
"license": "MIT",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"version": "0.0.0"
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
/* eslint-disable @typescript-eslint/no-var-requires */
|
||||
const path = require("path")
|
||||
const globalTypedocOptions = require("./typedoc")
|
||||
|
||||
const pathPrefix = path.join(__dirname, "..", "..")
|
||||
|
||||
module.exports = {
|
||||
...globalTypedocOptions,
|
||||
entryPoints: [path.join(pathPrefix, "packages/medusa/src/services/index.ts")],
|
||||
out: [path.join(pathPrefix, "www/apps/docs/content/references/services")],
|
||||
tsconfig: path.join(pathPrefix, "packages/medusa/tsconfig.json"),
|
||||
name: "Services Reference",
|
||||
indexTitle: "Services Reference",
|
||||
entryDocument: "index.md",
|
||||
hideInPageTOC: true,
|
||||
hideBreadcrumbs: true,
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"extends": "../../tsconfig",
|
||||
"compilerOptions": {
|
||||
"outDir": "./dist"
|
||||
},
|
||||
"include": ["*.js"]
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
dist
|
||||
.yarn
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
# typedoc-frontmatter-plugin
|
||||
# typedoc-plugin-frontmatter
|
||||
|
||||
A Typedoc plugin that allows inserting frontmatter key-value pairs at the top of the exported Markdown files.
|
||||
|
||||
@@ -34,7 +34,7 @@ frontmatterData: {
|
||||
},
|
||||
```
|
||||
|
||||
## Building the Plugin
|
||||
## Build the Plugin
|
||||
|
||||
Before using any command that makes use of this plugin, make sure to run the `build` command:
|
||||
|
||||
+13
-8
@@ -1,6 +1,11 @@
|
||||
{
|
||||
"name": "typedoc-frontmatter-plugin",
|
||||
"version": "1.0.0",
|
||||
"name": "typedoc-plugin-frontmatter",
|
||||
"private": true,
|
||||
"license": "MIT",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"version": "0.0.0",
|
||||
"description": "Plugin to add frontmatter key-values at the top of pages",
|
||||
"main": "./dist/index.js",
|
||||
"exports": "./dist/index.js",
|
||||
@@ -8,23 +13,23 @@
|
||||
"dist"
|
||||
],
|
||||
"author": "Shahed Nasser",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"build": "tsc"
|
||||
"build": "tsc",
|
||||
"watch": "tsc --watch",
|
||||
"lint": "eslint --ext .ts src"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typedoc": "0.22.x"
|
||||
"typedoc": "0.25.x"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^16.11.10",
|
||||
"typedoc": "^0.22.10",
|
||||
"typescript": "4.5.2"
|
||||
"typedoc": "^0.25.1",
|
||||
"typescript": "^4.6"
|
||||
},
|
||||
"keywords": [
|
||||
"typedocplugin",
|
||||
"packages",
|
||||
"monorepo",
|
||||
"lerna",
|
||||
"typedoc"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import { Application, PageEvent, ParameterType } from "typedoc"
|
||||
|
||||
export function load(app: Application) {
|
||||
app.options.addDeclaration({
|
||||
name: "frontmatterData",
|
||||
help: "An object of key-value pairs to be added to frontmatter",
|
||||
type: ParameterType.Mixed, // The default
|
||||
defaultValue: {},
|
||||
validate: (value: any) => {
|
||||
if (typeof value === "string") {
|
||||
//decode it with JSON to check if it's an object
|
||||
value = JSON.parse(value)
|
||||
}
|
||||
|
||||
if (
|
||||
!(typeof value === "object" && !Array.isArray(value) && value !== null)
|
||||
) {
|
||||
throw new Error("Value should be an object")
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
app.options.addDeclaration({
|
||||
name: "pagesPattern",
|
||||
help: "A string of pages pattern. The pattern will be tested using RegExp to determine whether the frontmatterData will be added or not.",
|
||||
type: ParameterType.String,
|
||||
defaultValue: "",
|
||||
})
|
||||
|
||||
app.renderer.on(PageEvent.END, (page: PageEvent) => {
|
||||
const patternStr: string | any = app.options.getValue("pagesPattern")
|
||||
const pattern = new RegExp(patternStr)
|
||||
let frontmatterData: object | any = app.options.getValue("frontmatterData")
|
||||
if (typeof frontmatterData === "string") {
|
||||
frontmatterData = JSON.parse(frontmatterData)
|
||||
}
|
||||
const frontmatterDataEntries = Object.entries(frontmatterData)
|
||||
|
||||
if (!frontmatterDataEntries.length || !pattern.test(page.filename)) {
|
||||
return
|
||||
}
|
||||
|
||||
let frontmatterStr = `---\n`
|
||||
|
||||
for (const [key, value] of frontmatterDataEntries) {
|
||||
frontmatterStr += `${key}: ${value}\n`
|
||||
}
|
||||
|
||||
frontmatterStr += `---\n\n`
|
||||
|
||||
page.contents = frontmatterStr + page.contents
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"extends": "../../tsconfig",
|
||||
"compilerOptions": {
|
||||
"outDir": "./dist"
|
||||
},
|
||||
"include": ["src"]
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
dist
|
||||
.yarn
|
||||
@@ -0,0 +1,28 @@
|
||||
# typedoc-plugin-markdown-medusa
|
||||
|
||||
A plugin that forks and customizes the [typedoc-plugin-markdown](https://github.com/tgreyuk/typedoc-plugin-markdown/tree/master/packages/typedoc-plugin-markdown) to create a theme with more formatting options.
|
||||
|
||||
## Configurations
|
||||
|
||||
Aside from the options detailed in [typedoc-plugin-markdown](https://github.com/tgreyuk/typedoc-plugin-markdown/tree/master/packages/typedoc-plugin-markdown#options), the following options are accepted:
|
||||
|
||||
- `formatting`: An object whose keys are string patterns used to target specific files. You can also use the string `*` to target all files. The values are objects having the following properties:
|
||||
- `sections`: (optional) an object whose keys are of type [`SectionKey`](./src/types.ts#L19) and values are boolean. This property is used to enable/disable certain sections in the outputted generated docs.
|
||||
- `reflectionGroups`: (optional) an object whose keys are titles of reflection groups (for example, `Constructors`), and values are boolean. This property is used to enable/disable reflection group from being documented.
|
||||
- `reflectionTitle`: (optional) an object used to customize how the title of a generated documentation page is rendered. It accepts the following properties:
|
||||
- `kind`: a boolean value indicating whether the documented resource's kind should be shown in the title.
|
||||
- `typeParameters`: a boolean value indicating whether the documented resource's type parameters should b shown in the title.
|
||||
- `suffix`: a string used to add additional text to the end of the page's title.
|
||||
- `reflectionDescription`: (optional) a string used to add description in a documentation page after the page's title.
|
||||
- `expandMembers`: (optional) a boolean indicating whether members in a page should be expanded. When enabled, the member titles (for example, `Methods`) are removed and the heading level of nested titles whithin the member is elevated by `1`.
|
||||
- `showCommentAsHeader`: (optional) a boolean indicating whether comments, for example, a method's name, are represented as headers.
|
||||
- `parameterStyle`: (optional) a string indicating how parameters are displayed. Its value can be `table` (default) or `list`.
|
||||
- `showReturnSignature`: (optional) a boolean indicating whether to show the signature for returned values.
|
||||
|
||||
## Build Plugin
|
||||
|
||||
Before using any command that makes use of this plugin, make sure to run the `build` command:
|
||||
|
||||
```bash
|
||||
yarn build
|
||||
```
|
||||
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"name": "typedoc-plugin-markdown-medusa",
|
||||
"private": true,
|
||||
"license": "MIT",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"version": "1.0.0",
|
||||
"description": "A plugin that creates a theme with customization capabilities.",
|
||||
"main": "./dist/index.js",
|
||||
"exports": "./dist/index.js",
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"author": "Shahed Nasser",
|
||||
"scripts": {
|
||||
"build": "tsc && copyfiles --up 1 ./src/**/*.hbs ./dist/",
|
||||
"lint": "eslint --ext .ts src"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typedoc": "0.25.x"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^16.11.10",
|
||||
"copyfiles": "^2.4.1",
|
||||
"typescript": "^4.6"
|
||||
},
|
||||
"keywords": [
|
||||
"typedocplugin",
|
||||
"packages",
|
||||
"monorepo",
|
||||
"typedoc"
|
||||
],
|
||||
"dependencies": {
|
||||
"handlebars": "^4.7.8"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import { ReflectionKind } from "typedoc"
|
||||
|
||||
const PLURALS = {
|
||||
[ReflectionKind.Class]: "Classes",
|
||||
[ReflectionKind.Property]: "Properties",
|
||||
[ReflectionKind.Enum]: "Enumerations",
|
||||
[ReflectionKind.EnumMember]: "Enumeration members",
|
||||
[ReflectionKind.TypeAlias]: "Type aliases",
|
||||
}
|
||||
|
||||
export function getKindPlural(kind: ReflectionKind): string {
|
||||
if (kind in PLURALS) {
|
||||
return PLURALS[kind as keyof typeof PLURALS]
|
||||
} else {
|
||||
return getKindString(kind) + "s"
|
||||
}
|
||||
}
|
||||
|
||||
function getKindString(kind: ReflectionKind): string {
|
||||
let str = ReflectionKind[kind]
|
||||
str = str.replace(/(.)([A-Z])/g, (_m, a, b) => a + " " + b.toLowerCase())
|
||||
return str
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
import { Application, ParameterType } from "typedoc"
|
||||
import { MarkdownThemeOptionsReader } from "./options-reader"
|
||||
import { MarkdownTheme } from "./theme"
|
||||
|
||||
export function load(app: Application) {
|
||||
app.renderer.defineTheme("markdown", MarkdownTheme)
|
||||
app.options.addReader(new MarkdownThemeOptionsReader())
|
||||
|
||||
app.options.addDeclaration({
|
||||
help: "[Markdown Plugin] Do not render page title.",
|
||||
name: "hidePageTitle",
|
||||
type: ParameterType.Boolean,
|
||||
defaultValue: false,
|
||||
})
|
||||
|
||||
app.options.addDeclaration({
|
||||
help: "[Markdown Plugin] Do not render breadcrumbs in template.",
|
||||
name: "hideBreadcrumbs",
|
||||
type: ParameterType.Boolean,
|
||||
defaultValue: false,
|
||||
})
|
||||
|
||||
app.options.addDeclaration({
|
||||
help: "[Markdown Plugin] Specifies the base path that all links to be served from. If omitted all urls will be relative.",
|
||||
name: "publicPath",
|
||||
type: ParameterType.String,
|
||||
})
|
||||
|
||||
app.options.addDeclaration({
|
||||
help: "[Markdown Plugin] Use HTML named anchors as fragment identifiers for engines that do not automatically assign header ids. Should be set for Bitbucket Server docs.",
|
||||
name: "namedAnchors",
|
||||
type: ParameterType.Boolean,
|
||||
defaultValue: false,
|
||||
})
|
||||
|
||||
app.options.addDeclaration({
|
||||
help: "[Markdown Plugin] Output all reflections into seperate output files.",
|
||||
name: "allReflectionsHaveOwnDocument",
|
||||
type: ParameterType.Boolean,
|
||||
defaultValue: false,
|
||||
})
|
||||
|
||||
app.options.addDeclaration({
|
||||
help: "[Markdown Plugin] Separator used to format filenames.",
|
||||
name: "filenameSeparator",
|
||||
type: ParameterType.String,
|
||||
defaultValue: ".",
|
||||
})
|
||||
|
||||
app.options.addDeclaration({
|
||||
help: "[Markdown Plugin] The file name of the entry document.",
|
||||
name: "entryDocument",
|
||||
type: ParameterType.String,
|
||||
defaultValue: "README.md",
|
||||
})
|
||||
|
||||
app.options.addDeclaration({
|
||||
help: "[Markdown Plugin] Do not render in-page table of contents items.",
|
||||
name: "hideInPageTOC",
|
||||
type: ParameterType.Boolean,
|
||||
defaultValue: false,
|
||||
})
|
||||
|
||||
app.options.addDeclaration({
|
||||
help: "[Markdown Plugin] Customise the index page title.",
|
||||
name: "indexTitle",
|
||||
type: ParameterType.String,
|
||||
})
|
||||
|
||||
app.options.addDeclaration({
|
||||
help: "[Markdown Plugin] Do not add special symbols for class members.",
|
||||
name: "hideMembersSymbol",
|
||||
type: ParameterType.Boolean,
|
||||
defaultValue: false,
|
||||
})
|
||||
|
||||
app.options.addDeclaration({
|
||||
help: "[Markdown Plugin] Preserve anchor casing when generating links.",
|
||||
name: "preserveAnchorCasing",
|
||||
type: ParameterType.Boolean,
|
||||
defaultValue: false,
|
||||
})
|
||||
|
||||
app.options.addDeclaration({
|
||||
help: "[Markdown Plugin] Specify the Type Declaration Render Style",
|
||||
name: "objectLiteralTypeDeclarationStyle",
|
||||
type: ParameterType.String,
|
||||
defaultValue: "table",
|
||||
validate: (x) => {
|
||||
const availableValues = ["table", "list"]
|
||||
if (!availableValues.includes(x)) {
|
||||
throw new Error(
|
||||
`Wrong value for objectLiteralTypeDeclarationStyle, the expected value is one of ${availableValues}`
|
||||
)
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
app.options.addDeclaration({
|
||||
help: "[Markdown Plugin] Formatting options that can be specified either on a specific document or to all documents",
|
||||
name: "formatting",
|
||||
type: ParameterType.Object,
|
||||
defaultValue: {},
|
||||
})
|
||||
}
|
||||
export { MarkdownTheme }
|
||||
@@ -0,0 +1,12 @@
|
||||
import { Options, OptionsReader } from "typedoc"
|
||||
|
||||
export class MarkdownThemeOptionsReader implements OptionsReader {
|
||||
name = "markdown-theme-reader"
|
||||
readonly order = 1000
|
||||
readonly supportsPackages = false
|
||||
read(container: Options) {
|
||||
if (container.getValue("theme") === "default") {
|
||||
container.setValue("theme", "markdown")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
import * as fs from "fs"
|
||||
import * as Handlebars from "handlebars"
|
||||
import * as path from "path"
|
||||
import breadcrumbsHelper from "./resources/helpers/breadcrumbs"
|
||||
import commentHelper from "./resources/helpers/comment"
|
||||
import commentsHelper from "./resources/helpers/comments"
|
||||
import declarationTitleHelper from "./resources/helpers/declaration-title"
|
||||
import escapeHelper from "./resources/helpers/escape"
|
||||
import hierarchyHelper from "./resources/helpers/hierarchy"
|
||||
import ifIsReference from "./resources/helpers/if-is-reference"
|
||||
import ifNamedAnchors from "./resources/helpers/if-named-anchors"
|
||||
import ifShowBreadcrumbsHelper from "./resources/helpers/if-show-breadcrumbs"
|
||||
import ifShowNamedAnchorsHelper from "./resources/helpers/if-show-named-anchors"
|
||||
import ifShowPageTitleHelper from "./resources/helpers/if-show-page-title"
|
||||
import ifShowReturnsHelper from "./resources/helpers/if-show-returns"
|
||||
import ifShowTypeHierarchyHelper from "./resources/helpers/if-show-type-hierarchy"
|
||||
import indexSignatureTitleHelper from "./resources/helpers/index-signature-title"
|
||||
import parameterTableHelper from "./resources/helpers/parameter-table"
|
||||
import objectLiteralMemberHelper from "./resources/helpers/type-declaration-object-literal"
|
||||
import referenceMember from "./resources/helpers/reference-member"
|
||||
import reflectionPathHelper from "./resources/helpers/reflection-path"
|
||||
import reflectionTitleHelper from "./resources/helpers/reflection-title"
|
||||
import relativeUrlHelper from "./resources/helpers/relative-url"
|
||||
import returns from "./resources/helpers/returns"
|
||||
import signatureTitleHelper from "./resources/helpers/signature-title"
|
||||
import tocHelper from "./resources/helpers/toc"
|
||||
import typeHelper from "./resources/helpers/type"
|
||||
import typeAndParentHelper from "./resources/helpers/type-and-parent"
|
||||
import typeParameterTableHelper from "./resources/helpers/type-parameter-table"
|
||||
import sectionsHelper from "./resources/helpers/section-enabled"
|
||||
import getFormattingOptionHelper from "./resources/helpers/get-formatting-option"
|
||||
import titleLevelHelper from "./resources/helpers/title-level"
|
||||
import typeParameterListHelper from "./resources/helpers/type-parameter-list"
|
||||
import typeParameterHelper from "./resources/helpers/type-parameter"
|
||||
import parameterListHelper from "./resources/helpers/parameter-list"
|
||||
import parameterHelper from "./resources/helpers/parameter"
|
||||
import { MarkdownTheme } from "./theme"
|
||||
|
||||
const TEMPLATE_PATH = path.join(__dirname, "resources", "templates")
|
||||
|
||||
export const indexTemplate = Handlebars.compile(
|
||||
fs.readFileSync(path.join(TEMPLATE_PATH, "index.hbs")).toString()
|
||||
)
|
||||
|
||||
export const reflectionTemplate = Handlebars.compile(
|
||||
fs.readFileSync(path.join(TEMPLATE_PATH, "reflection.hbs")).toString()
|
||||
)
|
||||
|
||||
export const reflectionMemberTemplate = Handlebars.compile(
|
||||
fs.readFileSync(path.join(TEMPLATE_PATH, "reflection.member.hbs")).toString()
|
||||
)
|
||||
|
||||
export function registerPartials() {
|
||||
const partialsFolder = path.join(__dirname, "resources", "partials")
|
||||
const partialFiles = fs.readdirSync(partialsFolder)
|
||||
partialFiles.forEach((partialFile) => {
|
||||
const partialName = path.basename(partialFile, ".hbs")
|
||||
const partialContent = fs
|
||||
.readFileSync(partialsFolder + "/" + partialFile)
|
||||
.toString()
|
||||
Handlebars.registerPartial(partialName, partialContent)
|
||||
})
|
||||
}
|
||||
|
||||
export function registerHelpers(theme: MarkdownTheme) {
|
||||
breadcrumbsHelper(theme)
|
||||
commentHelper(theme)
|
||||
commentsHelper(theme)
|
||||
declarationTitleHelper(theme)
|
||||
escapeHelper()
|
||||
hierarchyHelper()
|
||||
ifIsReference()
|
||||
ifNamedAnchors(theme)
|
||||
ifShowBreadcrumbsHelper(theme)
|
||||
ifShowNamedAnchorsHelper(theme)
|
||||
ifShowPageTitleHelper(theme)
|
||||
ifShowReturnsHelper()
|
||||
ifShowTypeHierarchyHelper()
|
||||
indexSignatureTitleHelper()
|
||||
parameterTableHelper()
|
||||
objectLiteralMemberHelper(theme)
|
||||
referenceMember()
|
||||
reflectionPathHelper()
|
||||
reflectionTitleHelper(theme)
|
||||
relativeUrlHelper(theme)
|
||||
returns()
|
||||
signatureTitleHelper(theme)
|
||||
tocHelper(theme)
|
||||
typeHelper()
|
||||
typeAndParentHelper()
|
||||
typeParameterTableHelper()
|
||||
sectionsHelper(theme)
|
||||
getFormattingOptionHelper(theme)
|
||||
titleLevelHelper(theme)
|
||||
typeParameterListHelper()
|
||||
typeParameterHelper(theme)
|
||||
parameterListHelper()
|
||||
parameterHelper(theme)
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
import * as Handlebars from "handlebars"
|
||||
import { PageEvent } from "typedoc"
|
||||
import { MarkdownTheme } from "../../theme"
|
||||
import { escapeChars, getDisplayName } from "../../utils"
|
||||
|
||||
export default function (theme: MarkdownTheme) {
|
||||
Handlebars.registerHelper("breadcrumbs", function (this: PageEvent) {
|
||||
const { entryPoints, entryDocument, project, readme } = theme
|
||||
|
||||
if (!project) {
|
||||
return ""
|
||||
}
|
||||
|
||||
const hasReadmeFile = !readme.endsWith("none")
|
||||
const breadcrumbs: string[] = []
|
||||
const globalsName = entryPoints.length > 1 ? "Modules" : "Exports"
|
||||
breadcrumbs.push(
|
||||
this.url === entryDocument
|
||||
? project.name
|
||||
: `[${getDisplayName(project)}](${Handlebars.helpers.relativeURL(
|
||||
entryDocument
|
||||
)})`
|
||||
)
|
||||
if (hasReadmeFile) {
|
||||
breadcrumbs.push(
|
||||
this.url === project.url
|
||||
? globalsName
|
||||
: `[${globalsName}](${Handlebars.helpers.relativeURL("modules.md")})`
|
||||
)
|
||||
}
|
||||
const breadcrumbsOut = breadcrumb(this, this.model, breadcrumbs)
|
||||
return breadcrumbsOut
|
||||
})
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
function breadcrumb(page: PageEvent, model: any, md: string[]) {
|
||||
if (model && model.parent) {
|
||||
breadcrumb(page, model.parent, md)
|
||||
if (model.url) {
|
||||
md.push(
|
||||
page.url === model.url
|
||||
? `${escapeChars(model.name)}`
|
||||
: `[${escapeChars(model.name)}](${Handlebars.helpers.relativeURL(
|
||||
model.url
|
||||
)})`
|
||||
)
|
||||
}
|
||||
}
|
||||
return md.join(" / ")
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
import * as fs from "fs"
|
||||
import * as Handlebars from "handlebars"
|
||||
import * as Path from "path"
|
||||
import { CommentDisplayPart } from "typedoc/dist/lib/models/comments/comment"
|
||||
import { MarkdownTheme } from "../../theme"
|
||||
|
||||
export default function (theme: MarkdownTheme) {
|
||||
Handlebars.registerHelper("comment", function (parts: CommentDisplayPart[]) {
|
||||
const result: string[] = []
|
||||
for (const part of parts) {
|
||||
switch (part.kind) {
|
||||
case "text":
|
||||
case "code":
|
||||
result.push(part.text)
|
||||
break
|
||||
case "inline-tag":
|
||||
switch (part.tag) {
|
||||
case "@label":
|
||||
case "@inheritdoc":
|
||||
break
|
||||
case "@link":
|
||||
case "@linkcode":
|
||||
case "@linkplain": {
|
||||
if (part.target) {
|
||||
const url =
|
||||
typeof part.target === "string"
|
||||
? part.target
|
||||
: "url" in part.target
|
||||
? Handlebars.helpers.relativeURL(part.target.url)
|
||||
: ""
|
||||
const wrap = part.tag === "@linkcode" ? "`" : ""
|
||||
result.push(
|
||||
url ? `[${wrap}${part.text}${wrap}](${url})` : part.text
|
||||
)
|
||||
} else {
|
||||
result.push(part.text)
|
||||
}
|
||||
break
|
||||
}
|
||||
default:
|
||||
result.push(`{${part.tag} ${part.text}}`)
|
||||
break
|
||||
}
|
||||
break
|
||||
default:
|
||||
result.push("")
|
||||
}
|
||||
}
|
||||
|
||||
return parseMarkdown(result.join(""), theme)
|
||||
})
|
||||
}
|
||||
|
||||
function parseMarkdown(text: string, theme: MarkdownTheme) {
|
||||
const includePattern = /\[\[include:([^\]]+?)\]\]/g
|
||||
const mediaPattern = /media:\/\/([^ ")\]}]+)/g
|
||||
|
||||
if (theme.includes) {
|
||||
text = text.replace(includePattern, (_match, path) => {
|
||||
path = Path.join(theme.includes!, path.trim())
|
||||
if (fs.existsSync(path) && fs.statSync(path).isFile()) {
|
||||
const contents = readFile(path)
|
||||
return contents
|
||||
} else {
|
||||
theme.application.logger.warn("Could not find file to include: " + path)
|
||||
return ""
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
if (theme.mediaDirectory) {
|
||||
text = text.replace(mediaPattern, (match: string, path: string) => {
|
||||
const fileName = Path.join(theme.mediaDirectory!, path)
|
||||
|
||||
if (fs.existsSync(fileName) && fs.statSync(fileName).isFile()) {
|
||||
return Handlebars.helpers.relativeURL("media") + "/" + path
|
||||
} else {
|
||||
theme.application.logger.warn("Could not find media file: " + fileName)
|
||||
return match
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return text
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the given file and return its contents.
|
||||
*
|
||||
* @param file The path of the file to read.
|
||||
* @returns The files contents.
|
||||
*/
|
||||
export function readFile(file: string): string {
|
||||
const buffer = fs.readFileSync(file)
|
||||
switch (buffer[0]) {
|
||||
case 0xfe:
|
||||
if (buffer[1] === 0xff) {
|
||||
let i = 0
|
||||
while (i + 1 < buffer.length) {
|
||||
const temp = buffer[i]
|
||||
buffer[i] = buffer[i + 1]
|
||||
buffer[i + 1] = temp
|
||||
i += 2
|
||||
}
|
||||
return buffer.toString("ucs2", 2)
|
||||
}
|
||||
break
|
||||
case 0xff:
|
||||
if (buffer[1] === 0xfe) {
|
||||
return buffer.toString("ucs2", 2)
|
||||
}
|
||||
break
|
||||
case 0xef:
|
||||
if (buffer[1] === 0xbb) {
|
||||
return buffer.toString("utf8", 3)
|
||||
}
|
||||
}
|
||||
|
||||
return buffer.toString("utf8", 0)
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
import * as Handlebars from "handlebars"
|
||||
import { Comment } from "typedoc"
|
||||
import { camelToTitleCase } from "../../utils"
|
||||
import { MarkdownTheme } from "../../theme"
|
||||
|
||||
export default function (theme: MarkdownTheme) {
|
||||
Handlebars.registerHelper(
|
||||
"comments",
|
||||
function (
|
||||
comment: Comment,
|
||||
showSummary = true,
|
||||
showTags = true,
|
||||
commentLevel = 4
|
||||
) {
|
||||
const { showCommentsAsHeader } = theme.getFormattingOptionsForLocation()
|
||||
const md: string[] = []
|
||||
|
||||
if (showSummary && comment.summary) {
|
||||
md.push(Handlebars.helpers.comment(comment.summary))
|
||||
}
|
||||
|
||||
const filteredTags = comment.blockTags.filter(
|
||||
(tag) => tag.tag !== "@returns"
|
||||
)
|
||||
|
||||
if (showTags && comment.blockTags?.length) {
|
||||
const tags = filteredTags.map((tag) => {
|
||||
return `${
|
||||
showCommentsAsHeader
|
||||
? `${Handlebars.helpers.titleLevel(commentLevel)} `
|
||||
: "**`"
|
||||
}${camelToTitleCase(tag.tag.substring(1))}${
|
||||
showCommentsAsHeader ? "" : "`**"
|
||||
}\n\n${Handlebars.helpers.comment(tag.content)}`
|
||||
})
|
||||
md.push(tags.join("\n\n"))
|
||||
}
|
||||
|
||||
return md.join("\n\n")
|
||||
}
|
||||
)
|
||||
}
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
import * as Handlebars from "handlebars"
|
||||
import {
|
||||
DeclarationReflection,
|
||||
LiteralType,
|
||||
ParameterReflection,
|
||||
ReflectionKind,
|
||||
ReflectionType,
|
||||
} from "typedoc"
|
||||
import { MarkdownTheme } from "../../theme"
|
||||
import {
|
||||
escapeChars,
|
||||
memberSymbol,
|
||||
stripComments,
|
||||
stripLineBreaks,
|
||||
} from "../../utils"
|
||||
|
||||
export default function (theme: MarkdownTheme) {
|
||||
Handlebars.registerHelper(
|
||||
"declarationTitle",
|
||||
function (this: ParameterReflection | DeclarationReflection) {
|
||||
const md = theme.hideMembersSymbol ? [] : [memberSymbol(this)]
|
||||
|
||||
function getType(
|
||||
reflection: ParameterReflection | DeclarationReflection
|
||||
) {
|
||||
const reflectionType = reflection.type as ReflectionType
|
||||
if (reflectionType && reflectionType.declaration?.children) {
|
||||
return ": `Object`"
|
||||
}
|
||||
return (
|
||||
(reflection.parent?.kindOf(ReflectionKind.Enum) ? " = " : ": ") +
|
||||
Handlebars.helpers.type.call(
|
||||
reflectionType ? reflectionType : reflection,
|
||||
"object"
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
if (this.flags && this.flags.length > 0 && !this.flags.isRest) {
|
||||
md.push(" " + this.flags.map((flag) => `\`${flag}\``).join(" "))
|
||||
}
|
||||
md.push(
|
||||
`${this.flags.isRest ? "... " : ""} **${escapeChars(this.name)}**`
|
||||
)
|
||||
if (this instanceof DeclarationReflection && this.typeParameters) {
|
||||
md.push(
|
||||
`<${this.typeParameters
|
||||
.map((typeParameter) => `\`${typeParameter.name}\``)
|
||||
.join(", ")}\\>`
|
||||
)
|
||||
}
|
||||
|
||||
md.push(getType(this))
|
||||
|
||||
if (
|
||||
!(this.type instanceof LiteralType) &&
|
||||
this.defaultValue &&
|
||||
this.defaultValue !== "..."
|
||||
) {
|
||||
md.push(` = \`${stripLineBreaks(stripComments(this.defaultValue))}\``)
|
||||
}
|
||||
return md.join("")
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import * as Handlebars from "handlebars"
|
||||
import { escapeChars } from "../../utils"
|
||||
|
||||
export default function () {
|
||||
Handlebars.registerHelper("escape", function (str: string) {
|
||||
return escapeChars(str)
|
||||
})
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
import { MarkdownTheme } from "../../theme"
|
||||
import * as Handlebars from "handlebars"
|
||||
|
||||
export default function (theme: MarkdownTheme) {
|
||||
Handlebars.registerHelper(
|
||||
"getFormattingOption",
|
||||
function (optionName: string): unknown {
|
||||
const options = theme.getFormattingOptionsForLocation()
|
||||
|
||||
return optionName in options
|
||||
? options[optionName as keyof typeof options]
|
||||
: null
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
import * as Handlebars from "handlebars"
|
||||
import { DeclarationHierarchy } from "typedoc/dist/lib/models"
|
||||
import { spaces } from "../../utils"
|
||||
|
||||
export default function () {
|
||||
Handlebars.registerHelper(
|
||||
"hierarchy",
|
||||
function (this: DeclarationHierarchy, level: number) {
|
||||
const md: string[] = []
|
||||
const symbol = level > 0 ? getSymbol(level) : "-"
|
||||
this.types.forEach((hierarchyType) => {
|
||||
if (this.isTarget) {
|
||||
md.push(`${symbol} **\`${hierarchyType}\`**`)
|
||||
} else {
|
||||
md.push(`${symbol} ${Handlebars.helpers.type.call(hierarchyType)}`)
|
||||
}
|
||||
})
|
||||
if (this.next) {
|
||||
md.push(Handlebars.helpers.hierarchy.call(this.next, level + 1))
|
||||
}
|
||||
return md.join("\n\n")
|
||||
}
|
||||
)
|
||||
|
||||
function getSymbol(level: number) {
|
||||
return spaces(2) + [...Array(level)].map(() => "↳").join("")
|
||||
}
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
import * as Handlebars from "handlebars"
|
||||
import { DeclarationReflection, ReferenceReflection } from "typedoc"
|
||||
|
||||
export default function () {
|
||||
Handlebars.registerHelper(
|
||||
"ifIsReference",
|
||||
function (
|
||||
this: DeclarationReflection | ReferenceReflection,
|
||||
options: Handlebars.HelperOptions
|
||||
) {
|
||||
return this instanceof ReferenceReflection
|
||||
? options.fn(this)
|
||||
: options.inverse(this)
|
||||
}
|
||||
)
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
import * as Handlebars from "handlebars"
|
||||
import { PageEvent } from "typedoc"
|
||||
import { MarkdownTheme } from "../../theme"
|
||||
|
||||
export default function (theme: MarkdownTheme) {
|
||||
Handlebars.registerHelper(
|
||||
"ifNamedAnchors",
|
||||
function (this: PageEvent, options: Handlebars.HelperOptions) {
|
||||
return theme.namedAnchors ? options.fn(this) : options.inverse(this)
|
||||
}
|
||||
)
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
import * as Handlebars from "handlebars"
|
||||
import { PageEvent } from "typedoc"
|
||||
import { MarkdownTheme } from "../../theme"
|
||||
|
||||
export default function (theme: MarkdownTheme) {
|
||||
Handlebars.registerHelper(
|
||||
"ifShowBreadcrumbs",
|
||||
function (this: PageEvent, options: Handlebars.HelperOptions) {
|
||||
return theme.hideBreadcrumbs ? options.inverse(this) : options.fn(this)
|
||||
}
|
||||
)
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
import * as Handlebars from "handlebars"
|
||||
import { PageEvent } from "typedoc"
|
||||
import { MarkdownTheme } from "../../theme"
|
||||
|
||||
export default function (theme: MarkdownTheme) {
|
||||
Handlebars.registerHelper(
|
||||
"ifShowNamedAnchors",
|
||||
function (this: PageEvent, options: Handlebars.HelperOptions) {
|
||||
return theme.namedAnchors ? options.fn(this) : options.inverse(this)
|
||||
}
|
||||
)
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
import * as Handlebars from "handlebars"
|
||||
import { PageEvent } from "typedoc"
|
||||
import { MarkdownTheme } from "../../theme"
|
||||
|
||||
export default function (theme: MarkdownTheme) {
|
||||
Handlebars.registerHelper(
|
||||
"ifShowPageTitle",
|
||||
function (this: PageEvent, options: Handlebars.HelperOptions) {
|
||||
return theme.hidePageTitle ? options.inverse(this) : options.fn(this)
|
||||
}
|
||||
)
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
import * as Handlebars from "handlebars"
|
||||
import { ReflectionKind, SignatureReflection } from "typedoc"
|
||||
|
||||
export default function () {
|
||||
Handlebars.registerHelper(
|
||||
"ifShowReturns",
|
||||
function (this: SignatureReflection, options: Handlebars.HelperOptions) {
|
||||
return this.type && !this.parent?.kindOf(ReflectionKind.Constructor)
|
||||
? options.fn(this)
|
||||
: options.inverse(this)
|
||||
}
|
||||
)
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
import * as Handlebars from "handlebars"
|
||||
import { DeclarationHierarchy, DeclarationReflection } from "typedoc"
|
||||
import { PageEvent } from "typedoc"
|
||||
|
||||
export default function () {
|
||||
Handlebars.registerHelper(
|
||||
"ifShowTypeHierarchy",
|
||||
function (
|
||||
this: PageEvent<DeclarationReflection>,
|
||||
options: Handlebars.HelperOptions
|
||||
) {
|
||||
const typeHierarchy = this.model?.typeHierarchy as DeclarationHierarchy
|
||||
return typeHierarchy && typeHierarchy.next
|
||||
? options.fn(this)
|
||||
: options.inverse(this)
|
||||
}
|
||||
)
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
import * as Handlebars from "handlebars"
|
||||
import { SignatureReflection } from "typedoc"
|
||||
|
||||
export default function () {
|
||||
Handlebars.registerHelper(
|
||||
"indexSignatureTitle",
|
||||
function (this: SignatureReflection) {
|
||||
const md = ["▪"]
|
||||
const parameters = this.parameters
|
||||
? this.parameters.map((parameter) => {
|
||||
return `${parameter.name}: ${Handlebars.helpers.type.call(
|
||||
parameter.type
|
||||
)}`
|
||||
})
|
||||
: []
|
||||
md.push(
|
||||
`[${parameters.join("")}]: ${Handlebars.helpers.type.call(this.type)}`
|
||||
)
|
||||
return md.join(" ")
|
||||
}
|
||||
)
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
import * as Handlebars from "handlebars"
|
||||
import reflectionFomatter from "../../utils/reflection-formatter"
|
||||
import { ReflectionParameterType } from "../../types"
|
||||
import { parseParams } from "../../utils/params-utils"
|
||||
|
||||
export default function () {
|
||||
Handlebars.registerHelper(
|
||||
"parameterList",
|
||||
|
||||
function (this: ReflectionParameterType[]) {
|
||||
return list(
|
||||
this.reduce(
|
||||
(acc: ReflectionParameterType[], current) =>
|
||||
parseParams(current, acc),
|
||||
[]
|
||||
)
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
function list(parameters: ReflectionParameterType[]) {
|
||||
const items = parameters.map((parameter) => {
|
||||
return reflectionFomatter(parameter)
|
||||
})
|
||||
|
||||
return items.join("\n")
|
||||
}
|
||||
+119
@@ -0,0 +1,119 @@
|
||||
import * as Handlebars from "handlebars"
|
||||
import { ParameterReflection, ReflectionType } from "typedoc"
|
||||
import { stripLineBreaks } from "../../utils"
|
||||
import { getReflectionType } from "./type"
|
||||
import { parseParams } from "../../utils/params-utils"
|
||||
import { ReflectionParameterType } from "../../types"
|
||||
|
||||
export default function () {
|
||||
Handlebars.registerHelper(
|
||||
"parameterTable",
|
||||
|
||||
function (this: ReflectionParameterType[]) {
|
||||
return table(
|
||||
this.reduce(
|
||||
(acc: ReflectionParameterType[], current: ReflectionParameterType) =>
|
||||
parseParams(current, acc),
|
||||
[]
|
||||
) as ParameterReflection[]
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
function table(parameters: ParameterReflection[]) {
|
||||
const showDefaults = hasDefaultValues(parameters)
|
||||
|
||||
const comments = parameters.map(
|
||||
(param: ParameterReflection) => !!param.comment?.hasVisibleComponent()
|
||||
)
|
||||
const hasComments = !comments.every((value) => !value)
|
||||
|
||||
const headers = ["Name", "Type"]
|
||||
|
||||
if (showDefaults) {
|
||||
headers.push("Default value")
|
||||
}
|
||||
|
||||
if (hasComments) {
|
||||
headers.push("Description")
|
||||
}
|
||||
|
||||
const rows = parameters.map((parameter) => {
|
||||
const row: string[] = []
|
||||
|
||||
const nbsp = " " // ? <== Unicode no-break space character
|
||||
const rest = parameter.flags.isRest ? "..." : ""
|
||||
const optional = parameter.flags.isOptional ? "?" : ""
|
||||
|
||||
const isDestructuredParam = parameter.name == "__namedParameters"
|
||||
const isDestructuredParamProp =
|
||||
parameter.name.startsWith("__namedParameters.")
|
||||
|
||||
if (isDestructuredParam) {
|
||||
row.push(`\`${rest}«destructured»\``)
|
||||
} else if (isDestructuredParamProp) {
|
||||
row.push(`›${nbsp}\`${rest}${parameter.name.slice(18)}${optional}\``)
|
||||
} else {
|
||||
row.push(`\`${rest}${parameter.name}${optional}\``)
|
||||
}
|
||||
|
||||
row.push(
|
||||
parameter.type
|
||||
? Handlebars.helpers.type.call(parameter.type, "object")
|
||||
: getReflectionType(parameter, "object")
|
||||
)
|
||||
|
||||
if (showDefaults) {
|
||||
row.push(getDefaultValue(parameter))
|
||||
}
|
||||
if (hasComments) {
|
||||
const comments = getComments(parameter)
|
||||
if (comments) {
|
||||
row.push(
|
||||
stripLineBreaks(Handlebars.helpers.comments(comments)).replace(
|
||||
/\|/g,
|
||||
"\\|"
|
||||
)
|
||||
)
|
||||
} else {
|
||||
row.push("-")
|
||||
}
|
||||
}
|
||||
return `| ${row.join(" | ")} |\n`
|
||||
})
|
||||
|
||||
const output = `\n| ${headers.join(" | ")} |\n| ${headers
|
||||
.map(() => ":------")
|
||||
.join(" | ")} |\n${rows.join("")}`
|
||||
return output
|
||||
}
|
||||
|
||||
function getDefaultValue(parameter: ParameterReflection) {
|
||||
return parameter.defaultValue && parameter.defaultValue !== "..."
|
||||
? `\`${parameter.defaultValue}\``
|
||||
: "`undefined`"
|
||||
}
|
||||
|
||||
function hasDefaultValues(parameters: ParameterReflection[]) {
|
||||
const defaultValues = (parameters as ParameterReflection[]).map(
|
||||
(param) =>
|
||||
param.defaultValue !== "{}" &&
|
||||
param.defaultValue !== "..." &&
|
||||
!!param.defaultValue
|
||||
)
|
||||
|
||||
return !defaultValues.every((value) => !value)
|
||||
}
|
||||
|
||||
function getComments(parameter: ParameterReflection) {
|
||||
if (parameter.type instanceof ReflectionType) {
|
||||
if (
|
||||
parameter.type?.declaration?.signatures &&
|
||||
parameter.type?.declaration?.signatures[0]?.comment
|
||||
) {
|
||||
return parameter.type?.declaration?.signatures[0]?.comment
|
||||
}
|
||||
}
|
||||
return parameter.comment
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import * as Handlebars from "handlebars"
|
||||
import { MarkdownTheme } from "../../theme"
|
||||
import { ParameterReflection } from "typedoc"
|
||||
|
||||
export default function (theme: MarkdownTheme) {
|
||||
Handlebars.registerHelper(
|
||||
"parameter",
|
||||
function (this: ParameterReflection[]) {
|
||||
const { parameterStyle } = theme.getFormattingOptionsForLocation()
|
||||
|
||||
if (parameterStyle === "list") {
|
||||
return Handlebars.helpers.parameterList.call(this)
|
||||
} else {
|
||||
return Handlebars.helpers.parameterTable.call(this)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
import * as Handlebars from "handlebars"
|
||||
import { ReferenceReflection } from "typedoc"
|
||||
|
||||
export default function () {
|
||||
Handlebars.registerHelper(
|
||||
"referenceMember",
|
||||
function (this: ReferenceReflection) {
|
||||
const referenced = this.tryGetTargetReflectionDeep()
|
||||
|
||||
if (!referenced) {
|
||||
return `Re-exports ${this.name}`
|
||||
}
|
||||
|
||||
if (this.name === referenced.name) {
|
||||
return `Re-exports [${
|
||||
referenced.name
|
||||
}](${Handlebars.helpers.relativeURL(referenced.url)})`
|
||||
}
|
||||
|
||||
return `Renames and re-exports [${
|
||||
referenced.name
|
||||
}](${Handlebars.helpers.relativeURL(referenced.url)})`
|
||||
}
|
||||
)
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
import * as Handlebars from "handlebars"
|
||||
import { ContainerReflection, ReflectionKind } from "typedoc"
|
||||
import { PageEvent } from "typedoc/dist/lib/output/events"
|
||||
|
||||
export default function () {
|
||||
Handlebars.registerHelper(
|
||||
"reflectionPath",
|
||||
|
||||
function (this: PageEvent<ContainerReflection>) {
|
||||
if (this.model) {
|
||||
if (this.model.kind && this.model.kind !== ReflectionKind.Module) {
|
||||
const title: string[] = []
|
||||
if (this.model.parent && this.model.parent.parent) {
|
||||
if (this.model.parent.parent.parent) {
|
||||
title.push(
|
||||
`[${
|
||||
this.model.parent.parent.name
|
||||
}](${Handlebars.helpers.relativeURL(
|
||||
this.model?.parent?.parent.url
|
||||
)})`
|
||||
)
|
||||
}
|
||||
title.push(
|
||||
`[${this.model.parent.name}](${Handlebars.helpers.relativeURL(
|
||||
this.model.parent.url
|
||||
)})`
|
||||
)
|
||||
}
|
||||
title.push(this.model.name)
|
||||
return title.length > 1 ? `${title.join(".")}` : null
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
)
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
import * as Handlebars from "handlebars"
|
||||
import { PageEvent, ParameterReflection, ReflectionKind } from "typedoc"
|
||||
import { MarkdownTheme } from "../../theme"
|
||||
import { escapeChars, getDisplayName } from "../../utils"
|
||||
|
||||
export default function (theme: MarkdownTheme) {
|
||||
Handlebars.registerHelper(
|
||||
"reflectionTitle",
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
function (this: PageEvent<any>, shouldEscape = true) {
|
||||
const { reflectionTitle } = theme.getFormattingOptionsForLocation()
|
||||
|
||||
const title: string[] = [""]
|
||||
if (
|
||||
reflectionTitle?.kind &&
|
||||
this.model?.kind &&
|
||||
this.url !== this.project.url
|
||||
) {
|
||||
title.push(`${ReflectionKind.singularString(this.model.kind)}: `)
|
||||
}
|
||||
if (this.url === this.project.url) {
|
||||
title.push(theme.indexTitle || getDisplayName(this.model))
|
||||
} else {
|
||||
title.push(
|
||||
shouldEscape ? escapeChars(this.model.name) : this.model.name
|
||||
)
|
||||
if (reflectionTitle?.typeParameters && this.model.typeParameters) {
|
||||
const typeParameters = this.model.typeParameters
|
||||
.map((typeParameter: ParameterReflection) => typeParameter.name)
|
||||
.join(", ")
|
||||
title.push(`<${typeParameters}${shouldEscape ? "\\>" : ">"}`)
|
||||
}
|
||||
}
|
||||
if (reflectionTitle?.suffix) {
|
||||
title.push(` ${reflectionTitle.suffix}`)
|
||||
}
|
||||
return title.join("")
|
||||
}
|
||||
)
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
import * as Handlebars from "handlebars"
|
||||
|
||||
import { MarkdownTheme } from "../../theme"
|
||||
|
||||
export default function (theme: MarkdownTheme) {
|
||||
Handlebars.registerHelper("relativeURL", function (url: string) {
|
||||
return url
|
||||
? theme.publicPath
|
||||
? theme.publicPath + url
|
||||
: theme.getRelativeUrl(url)
|
||||
: url
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
import * as Handlebars from "handlebars"
|
||||
import { Comment, DeclarationReflection } from "typedoc"
|
||||
import reflectionFomatter from "../../utils/reflection-formatter"
|
||||
|
||||
export default function () {
|
||||
Handlebars.registerHelper("returns", function (comment: Comment) {
|
||||
const md: string[] = []
|
||||
|
||||
if (comment.blockTags?.length) {
|
||||
const tags = comment.blockTags
|
||||
.filter((tag) => tag.tag === "@returns")
|
||||
.map((tag) => {
|
||||
let result = Handlebars.helpers.comment(tag.content)
|
||||
tag.content.forEach((commentPart) => {
|
||||
if (
|
||||
"target" in commentPart &&
|
||||
commentPart.target instanceof DeclarationReflection
|
||||
) {
|
||||
const content = commentPart.target.children?.map((childItem) =>
|
||||
reflectionFomatter(childItem)
|
||||
)
|
||||
result += `\n\n<details>\n<summary>\n${
|
||||
commentPart.target.name
|
||||
}\n</summary>\n\n${content?.join("\n")}\n\n</details>`
|
||||
}
|
||||
})
|
||||
return result
|
||||
})
|
||||
md.push(tags.join("\n\n"))
|
||||
}
|
||||
|
||||
return md.join("")
|
||||
})
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
import { MarkdownTheme } from "../../theme"
|
||||
import * as Handlebars from "handlebars"
|
||||
|
||||
export default function (theme: MarkdownTheme) {
|
||||
Handlebars.registerHelper(
|
||||
"sectionEnabled",
|
||||
function (sectionName: string): boolean {
|
||||
const { sections } = theme.getFormattingOptionsForLocation()
|
||||
|
||||
return !sections || !(sectionName in sections) || sections[sectionName]
|
||||
}
|
||||
)
|
||||
}
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
import * as Handlebars from "handlebars"
|
||||
import {
|
||||
ParameterReflection,
|
||||
ReflectionKind,
|
||||
SignatureReflection,
|
||||
} from "typedoc"
|
||||
import { memberSymbol } from "../../utils"
|
||||
import { MarkdownTheme } from "../../theme"
|
||||
|
||||
export default function (theme: MarkdownTheme) {
|
||||
Handlebars.registerHelper(
|
||||
"signatureTitle",
|
||||
function (this: SignatureReflection, accessor?: string, standalone = true) {
|
||||
const md: string[] = []
|
||||
|
||||
if (standalone && !theme.hideMembersSymbol) {
|
||||
md.push(`${memberSymbol(this)} `)
|
||||
}
|
||||
|
||||
if (this.parent && this.parent.flags?.length > 0) {
|
||||
md.push(this.parent.flags.map((flag) => `\`${flag}\``).join(" ") + " ")
|
||||
}
|
||||
|
||||
if (accessor) {
|
||||
md.push(`\`${accessor}\` **${this.name}**`)
|
||||
} else if (this.name !== "__call" && this.name !== "__type") {
|
||||
md.push(`**${this.name}**`)
|
||||
}
|
||||
|
||||
if (this.typeParameters) {
|
||||
md.push(
|
||||
`<${this.typeParameters
|
||||
.map((typeParameter) => `\`${typeParameter.name}\``)
|
||||
.join(", ")}\\>`
|
||||
)
|
||||
}
|
||||
md.push(`(${getParameters(this.parameters)})`)
|
||||
|
||||
if (this.type && !this.parent?.kindOf(ReflectionKind.Constructor)) {
|
||||
md.push(`: ${Handlebars.helpers.type.call(this.type, "object")}`)
|
||||
}
|
||||
return md.join("") + (standalone ? "\n" : "")
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
const getParameters = (
|
||||
parameters: ParameterReflection[] = [],
|
||||
backticks = true
|
||||
) => {
|
||||
return parameters
|
||||
.map((param) => {
|
||||
const isDestructuredParam = param.name == "__namedParameters"
|
||||
const paramItem = `${param.flags.isRest ? "..." : ""}${
|
||||
isDestructuredParam ? "«destructured»" : param.name
|
||||
}${param.flags.isOptional || param.defaultValue ? "?" : ""}`
|
||||
return backticks ? `\`${paramItem}\`` : paramItem
|
||||
})
|
||||
.join(", ")
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
import { MarkdownTheme } from "../../theme"
|
||||
import * as Handlebars from "handlebars"
|
||||
|
||||
export default function (theme: MarkdownTheme) {
|
||||
Handlebars.registerHelper("titleLevel", function (originalLevel = 3): string {
|
||||
const { expandMembers } = theme.getFormattingOptionsForLocation()
|
||||
|
||||
const level = expandMembers ? originalLevel - 1 : originalLevel
|
||||
|
||||
return Array(level).fill("#").join("")
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
import * as Handlebars from "handlebars"
|
||||
import {
|
||||
DeclarationReflection,
|
||||
ProjectReflection,
|
||||
ReflectionGroup,
|
||||
} from "typedoc"
|
||||
import { MarkdownTheme } from "../../theme"
|
||||
import { escapeChars } from "../../utils"
|
||||
|
||||
export default function (theme: MarkdownTheme) {
|
||||
Handlebars.registerHelper(
|
||||
"toc",
|
||||
function (this: ProjectReflection | DeclarationReflection) {
|
||||
const md: string[] = []
|
||||
|
||||
const { hideInPageTOC } = theme
|
||||
|
||||
const isVisible = this.groups?.some((group) =>
|
||||
group.allChildrenHaveOwnDocument()
|
||||
)
|
||||
|
||||
function pushGroup(group: ReflectionGroup, md: string[]) {
|
||||
const children = group.children.map(
|
||||
(child) =>
|
||||
`- [${escapeChars(child.name)}](${Handlebars.helpers.relativeURL(
|
||||
child.url
|
||||
)})`
|
||||
)
|
||||
md.push(children.join("\n"))
|
||||
}
|
||||
|
||||
if ((!hideInPageTOC && this.groups) || (isVisible && this.groups)) {
|
||||
if (!hideInPageTOC) {
|
||||
md.push(`## Table of contents\n\n`)
|
||||
}
|
||||
const headingLevel = hideInPageTOC ? `##` : `###`
|
||||
this.groups?.forEach((group) => {
|
||||
const groupTitle = group.title
|
||||
if (group.categories) {
|
||||
group.categories.forEach((category) => {
|
||||
md.push(`${headingLevel} ${category.title} ${groupTitle}\n\n`)
|
||||
pushGroup(category as ReflectionGroup, md)
|
||||
md.push("\n")
|
||||
})
|
||||
} else {
|
||||
if (!hideInPageTOC || group.allChildrenHaveOwnDocument()) {
|
||||
md.push(`${headingLevel} ${groupTitle}\n\n`)
|
||||
pushGroup(group, md)
|
||||
md.push("\n")
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
return md.length > 0 ? md.join("\n") : null
|
||||
}
|
||||
)
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
import * as Handlebars from "handlebars"
|
||||
import { SignatureReflection } from "typedoc"
|
||||
import { ArrayType, ReferenceType } from "typedoc/dist/lib/models/types"
|
||||
import { escapeChars } from "../../utils"
|
||||
|
||||
export default function () {
|
||||
Handlebars.registerHelper(
|
||||
"typeAndParent",
|
||||
function (this: ArrayType | ReferenceType) {
|
||||
const getUrl = (name: string, url: string) =>
|
||||
`[${name}](${Handlebars.helpers.relativeURL(url)})`
|
||||
if (this) {
|
||||
if ("elementType" in this) {
|
||||
return Handlebars.helpers.typeAndParent.call(this.elementType) + "[]"
|
||||
} else {
|
||||
if (this.reflection) {
|
||||
const md: string[] = []
|
||||
if (this.reflection instanceof SignatureReflection) {
|
||||
if (this.reflection.parent?.parent?.url) {
|
||||
md.push(
|
||||
getUrl(
|
||||
this.reflection.parent.parent.name,
|
||||
this.reflection.parent.parent.url
|
||||
)
|
||||
)
|
||||
if (this.reflection.parent.url) {
|
||||
md.push(
|
||||
getUrl(
|
||||
this.reflection.parent.name,
|
||||
this.reflection.parent.url
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (this.reflection.parent?.url) {
|
||||
md.push(
|
||||
getUrl(
|
||||
this.reflection.parent.name,
|
||||
this.reflection.parent.url
|
||||
)
|
||||
)
|
||||
if (this.reflection.url) {
|
||||
md.push(getUrl(this.reflection.name, this.reflection.url))
|
||||
}
|
||||
}
|
||||
}
|
||||
return md.join(".")
|
||||
} else {
|
||||
return escapeChars(this.toString())
|
||||
}
|
||||
}
|
||||
}
|
||||
return "void"
|
||||
}
|
||||
)
|
||||
}
|
||||
+139
@@ -0,0 +1,139 @@
|
||||
import * as Handlebars from "handlebars"
|
||||
import { DeclarationReflection, ReflectionType } from "typedoc"
|
||||
import { MarkdownTheme } from "../../theme"
|
||||
import { escapeChars, stripLineBreaks } from "../../utils"
|
||||
import reflectionFomatter from "../../utils/reflection-formatter"
|
||||
import { parseParams } from "../../utils/params-utils"
|
||||
import { ReflectionParameterType } from "../../types"
|
||||
|
||||
export default function (theme: MarkdownTheme) {
|
||||
Handlebars.registerHelper(
|
||||
"typeDeclarationMembers",
|
||||
function (this: DeclarationReflection[]) {
|
||||
const comments = this.map(
|
||||
(param) => !!param.comment?.hasVisibleComponent()
|
||||
)
|
||||
const hasComments = !comments.every((value) => !value)
|
||||
|
||||
const properties = this.reduce(
|
||||
(acc: ReflectionParameterType[], current: ReflectionParameterType) =>
|
||||
parseParams(current, acc),
|
||||
[]
|
||||
) as DeclarationReflection[]
|
||||
|
||||
let result = ""
|
||||
switch (theme.objectLiteralTypeDeclarationStyle) {
|
||||
case "list": {
|
||||
result = getListMarkdownContent(properties)
|
||||
break
|
||||
}
|
||||
case "table": {
|
||||
result = getTableMarkdownContent(properties, hasComments)
|
||||
break
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
function getListMarkdownContent(properties: DeclarationReflection[]) {
|
||||
const items = properties.map((property) => reflectionFomatter(property))
|
||||
|
||||
return items.join("\n")
|
||||
}
|
||||
|
||||
function getTableMarkdownContent(
|
||||
properties: DeclarationReflection[],
|
||||
hasComments: boolean
|
||||
) {
|
||||
const headers = ["Name", "Type"]
|
||||
|
||||
if (hasComments) {
|
||||
headers.push("Description")
|
||||
}
|
||||
const rows = properties.map((property) => {
|
||||
const propertyType = getPropertyType(property)
|
||||
const row: string[] = []
|
||||
const nameCol: string[] = []
|
||||
const name =
|
||||
property.name.match(/[\\`\\|]/g) !== null
|
||||
? escapeChars(getName(property))
|
||||
: `\`${getName(property)}\``
|
||||
nameCol.push(name)
|
||||
row.push(nameCol.join(" "))
|
||||
row.push(
|
||||
Handlebars.helpers.type.call(propertyType).replace(/(?<!\\)\|/g, "\\|")
|
||||
)
|
||||
|
||||
if (hasComments) {
|
||||
const comments = getComments(property)
|
||||
if (comments) {
|
||||
row.push(
|
||||
stripLineBreaks(Handlebars.helpers.comments(comments)).replace(
|
||||
/\|/g,
|
||||
"\\|"
|
||||
)
|
||||
)
|
||||
} else {
|
||||
row.push("-")
|
||||
}
|
||||
}
|
||||
return `| ${row.join(" | ")} |\n`
|
||||
})
|
||||
|
||||
const output = `\n| ${headers.join(" | ")} |\n| ${headers
|
||||
.map(() => ":------")
|
||||
.join(" | ")} |\n${rows.join("")}`
|
||||
return output
|
||||
}
|
||||
|
||||
function getPropertyType(property: DeclarationReflection) {
|
||||
if (property.getSignature) {
|
||||
return property.getSignature.type
|
||||
}
|
||||
if (property.setSignature) {
|
||||
return property.setSignature.type
|
||||
}
|
||||
return property.type ? property.type : property
|
||||
}
|
||||
|
||||
function getName(property: DeclarationReflection) {
|
||||
const md: string[] = []
|
||||
if (property.flags.isRest) {
|
||||
md.push("...")
|
||||
}
|
||||
if (property.getSignature) {
|
||||
md.push(`get ${property.getSignature.name}()`)
|
||||
} else if (property.setSignature) {
|
||||
md.push(
|
||||
`set ${
|
||||
property.setSignature.name
|
||||
}(${property.setSignature.parameters?.map((parameter) => {
|
||||
return `${parameter.name}:${Handlebars.helpers.type.call(
|
||||
parameter.type,
|
||||
"all",
|
||||
false
|
||||
)}`
|
||||
})})`
|
||||
)
|
||||
} else {
|
||||
md.push(property.name)
|
||||
}
|
||||
if (property.flags.isOptional) {
|
||||
md.push("?")
|
||||
}
|
||||
return md.join("")
|
||||
}
|
||||
|
||||
function getComments(property: DeclarationReflection) {
|
||||
if (property.type instanceof ReflectionType) {
|
||||
if (property.type?.declaration?.signatures) {
|
||||
return property.type?.declaration.signatures[0].comment
|
||||
}
|
||||
}
|
||||
if (property.signatures?.length) {
|
||||
return property.signatures[0].comment
|
||||
}
|
||||
return property.comment
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
import * as Handlebars from "handlebars"
|
||||
import { TypeParameterReflection } from "typedoc"
|
||||
import reflectionFomatter from "../../utils/reflection-formatter"
|
||||
|
||||
export default function () {
|
||||
Handlebars.registerHelper(
|
||||
"typeParameterList",
|
||||
function (this: TypeParameterReflection[]) {
|
||||
return list(this)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
function list(parameters: TypeParameterReflection[]) {
|
||||
const items = parameters.map((parameter) => reflectionFomatter(parameter))
|
||||
|
||||
return items.join("\n")
|
||||
}
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
import * as Handlebars from "handlebars"
|
||||
import { TypeParameterReflection } from "typedoc"
|
||||
import { stripLineBreaks } from "../../utils"
|
||||
|
||||
export default function () {
|
||||
Handlebars.registerHelper(
|
||||
"typeParameterTable",
|
||||
function (this: TypeParameterReflection[]) {
|
||||
return table(this)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
function table(parameters: TypeParameterReflection[]) {
|
||||
const showTypeCol = hasTypes(parameters)
|
||||
|
||||
const comments = parameters.map(
|
||||
(param: TypeParameterReflection) => !!param.comment?.hasVisibleComponent()
|
||||
)
|
||||
|
||||
const hasComments = !comments.every((value) => !value)
|
||||
|
||||
const headers = ["Name"]
|
||||
|
||||
if (showTypeCol) {
|
||||
headers.push("Type")
|
||||
}
|
||||
|
||||
if (hasComments) {
|
||||
headers.push("Description")
|
||||
}
|
||||
|
||||
const rows = parameters.map((parameter: TypeParameterReflection) => {
|
||||
const row: string[] = []
|
||||
|
||||
row.push(`\`${parameter.name}\``)
|
||||
|
||||
if (showTypeCol) {
|
||||
const typeCol: string[] = []
|
||||
if (!parameter.type && !parameter.default) {
|
||||
typeCol.push(`\`${parameter.name}\``)
|
||||
}
|
||||
if (parameter.type) {
|
||||
typeCol.push(
|
||||
`extends ${Handlebars.helpers.type.call(parameter.type, "object")}`
|
||||
)
|
||||
}
|
||||
if (parameter.default) {
|
||||
if (parameter.type) {
|
||||
typeCol.push(" = ")
|
||||
}
|
||||
typeCol.push(Handlebars.helpers.type.call(parameter.default))
|
||||
}
|
||||
row.push(typeCol.join(""))
|
||||
}
|
||||
|
||||
if (hasComments) {
|
||||
if (parameter.comment?.summary) {
|
||||
row.push(
|
||||
stripLineBreaks(
|
||||
Handlebars.helpers.comment(parameter.comment?.summary)
|
||||
).replace(/\|/g, "\\|")
|
||||
)
|
||||
} else {
|
||||
row.push("-")
|
||||
}
|
||||
}
|
||||
return `| ${row.join(" | ")} |\n`
|
||||
})
|
||||
|
||||
const output = `\n| ${headers.join(" | ")} |\n| ${headers
|
||||
.map(() => ":------")
|
||||
.join(" | ")} |\n${rows.join("")}`
|
||||
return output
|
||||
}
|
||||
|
||||
function hasTypes(parameters: TypeParameterReflection[]) {
|
||||
const types = (parameters as TypeParameterReflection[]).map(
|
||||
(param) => !!param.type || !!param.default
|
||||
)
|
||||
return !types.every((value) => !value)
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
import * as Handlebars from "handlebars"
|
||||
import { MarkdownTheme } from "../../theme"
|
||||
import { TypeParameterReflection } from "typedoc"
|
||||
|
||||
export default function (theme: MarkdownTheme) {
|
||||
Handlebars.registerHelper(
|
||||
"typeParameter",
|
||||
function (this: TypeParameterReflection[]) {
|
||||
const { parameterStyle } = theme.getFormattingOptionsForLocation()
|
||||
|
||||
if (parameterStyle === "list") {
|
||||
return Handlebars.helpers.typeParameterList.call(this)
|
||||
} else {
|
||||
return Handlebars.helpers.typeParameterTable.call(this)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,306 @@
|
||||
import * as Handlebars from "handlebars"
|
||||
import {
|
||||
ArrayType,
|
||||
ConditionalType,
|
||||
DeclarationReflection,
|
||||
IndexedAccessType,
|
||||
InferredType,
|
||||
IntersectionType,
|
||||
IntrinsicType,
|
||||
LiteralType,
|
||||
PredicateType,
|
||||
QueryType,
|
||||
ReferenceType,
|
||||
ReflectionType,
|
||||
SignatureReflection,
|
||||
TupleType,
|
||||
TypeOperatorType,
|
||||
UnionType,
|
||||
UnknownType,
|
||||
} from "typedoc"
|
||||
import { escapeChars } from "../../utils"
|
||||
import { ReflectionParameterType } from "../../types"
|
||||
|
||||
type Collapse = "object" | "function" | "all" | "none"
|
||||
|
||||
export default function () {
|
||||
Handlebars.registerHelper(
|
||||
"type",
|
||||
function (
|
||||
this:
|
||||
| ArrayType
|
||||
| IntersectionType
|
||||
| IntrinsicType
|
||||
| ReferenceType
|
||||
| TupleType
|
||||
| UnionType
|
||||
| TypeOperatorType
|
||||
| QueryType
|
||||
| PredicateType
|
||||
| ReferenceType
|
||||
| ConditionalType
|
||||
| IndexedAccessType
|
||||
| UnknownType
|
||||
| InferredType,
|
||||
|
||||
collapse: Collapse = "none",
|
||||
emphasis = true
|
||||
) {
|
||||
if (this instanceof ReferenceType) {
|
||||
return getReferenceType(this, emphasis)
|
||||
}
|
||||
|
||||
if (this instanceof ArrayType && this.elementType) {
|
||||
return getArrayType(this, emphasis)
|
||||
}
|
||||
|
||||
if (this instanceof UnionType && this.types) {
|
||||
return getUnionType(this, emphasis)
|
||||
}
|
||||
|
||||
if (this instanceof IntersectionType && this.types) {
|
||||
return getIntersectionType(this)
|
||||
}
|
||||
|
||||
if (this instanceof TupleType && this.elements) {
|
||||
return getTupleType(this)
|
||||
}
|
||||
|
||||
if (this instanceof IntrinsicType && this.name) {
|
||||
return getIntrinsicType(this, emphasis)
|
||||
}
|
||||
|
||||
if (this instanceof ReflectionType) {
|
||||
return getReflectionType(this, collapse)
|
||||
}
|
||||
|
||||
if (this instanceof DeclarationReflection) {
|
||||
return getReflectionType(this, collapse)
|
||||
}
|
||||
|
||||
if (this instanceof TypeOperatorType) {
|
||||
return getTypeOperatorType(this)
|
||||
}
|
||||
|
||||
if (this instanceof QueryType) {
|
||||
return getQueryType(this)
|
||||
}
|
||||
|
||||
if (this instanceof ConditionalType) {
|
||||
return getConditionalType(this)
|
||||
}
|
||||
|
||||
if (this instanceof IndexedAccessType) {
|
||||
return getIndexAccessType(this)
|
||||
}
|
||||
|
||||
if (this instanceof UnknownType) {
|
||||
return getUnknownType(this)
|
||||
}
|
||||
|
||||
if (this instanceof InferredType) {
|
||||
return getInferredType(this)
|
||||
}
|
||||
|
||||
if (this instanceof LiteralType) {
|
||||
return getLiteralType(this)
|
||||
}
|
||||
|
||||
return this ? escapeChars(this.toString()) : ""
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
function getLiteralType(model: LiteralType) {
|
||||
if (typeof model.value === "bigint") {
|
||||
return `\`${model.value}n\``
|
||||
}
|
||||
return `\`\`${JSON.stringify(model.value)}\`\``
|
||||
}
|
||||
|
||||
export function getReflectionType(
|
||||
model: ReflectionParameterType,
|
||||
collapse: Collapse
|
||||
) {
|
||||
const root = model instanceof ReflectionType ? model.declaration : model
|
||||
if ("signatures" in root && root.signatures) {
|
||||
return collapse === "function" || collapse === "all"
|
||||
? `\`fn\``
|
||||
: getFunctionType(root.signatures)
|
||||
}
|
||||
return collapse === "object" || collapse === "all"
|
||||
? `\`Object\``
|
||||
: getDeclarationType(root as DeclarationReflection)
|
||||
}
|
||||
|
||||
export function getDeclarationType(model: DeclarationReflection) {
|
||||
if (model.indexSignature || model.children) {
|
||||
let indexSignature = ""
|
||||
const declarationIndexSignature = model.indexSignature
|
||||
if (declarationIndexSignature) {
|
||||
const key = declarationIndexSignature.parameters
|
||||
? declarationIndexSignature.parameters.map(
|
||||
(param) => `\`[${param.name}: ${param.type}]\``
|
||||
)
|
||||
: ""
|
||||
const obj = Handlebars.helpers.type.call(declarationIndexSignature.type)
|
||||
indexSignature = `${key}: ${obj}; `
|
||||
}
|
||||
const types =
|
||||
model.children &&
|
||||
model.children.map((obj) => {
|
||||
return `\`${obj.name}${
|
||||
obj.flags.isOptional ? "?" : ""
|
||||
}\`: ${Handlebars.helpers.type.call(
|
||||
obj.signatures || obj.children ? obj : obj.type
|
||||
)} ${
|
||||
obj.defaultValue && obj.defaultValue !== "..."
|
||||
? `= ${escapeChars(obj.defaultValue)}`
|
||||
: ""
|
||||
}`
|
||||
})
|
||||
return `{ ${indexSignature ? indexSignature : ""}${
|
||||
types ? types.join("; ") : ""
|
||||
} }${
|
||||
model.defaultValue && model.defaultValue !== "..."
|
||||
? `= ${escapeChars(model.defaultValue)}`
|
||||
: ""
|
||||
}`
|
||||
}
|
||||
return "{}"
|
||||
}
|
||||
|
||||
export function getFunctionType(modelSignatures: SignatureReflection[]) {
|
||||
const functions = modelSignatures.map((fn) => {
|
||||
const typeParams = fn.typeParameters
|
||||
? `<${fn.typeParameters
|
||||
.map((typeParameter) => typeParameter.name)
|
||||
.join(", ")}\\>`
|
||||
: []
|
||||
const params = fn.parameters
|
||||
? fn.parameters.map((param) => {
|
||||
return `${param.flags.isRest ? "..." : ""}\`${param.name}${
|
||||
param.flags.isOptional ? "?" : ""
|
||||
}\`: ${Handlebars.helpers.type.call(param.type ? param.type : param)}`
|
||||
})
|
||||
: []
|
||||
const returns = Handlebars.helpers.type.call(fn.type)
|
||||
return typeParams + `(${params.join(", ")}) => ${returns}`
|
||||
})
|
||||
return functions.join("")
|
||||
}
|
||||
|
||||
export function getReferenceType(model: ReferenceType, emphasis: boolean) {
|
||||
if (model.reflection || (model.name && model.typeArguments)) {
|
||||
const reflection: string[] = []
|
||||
|
||||
if (model.reflection?.url) {
|
||||
reflection.push(
|
||||
`[${`\`${model.reflection.name}\``}](${Handlebars.helpers.relativeURL(
|
||||
model.reflection.url
|
||||
)})`
|
||||
)
|
||||
} else {
|
||||
reflection.push(
|
||||
model.externalUrl
|
||||
? `[${`\`${model.name}\``}]( ${model.externalUrl} )`
|
||||
: `\`${model.name}\``
|
||||
)
|
||||
}
|
||||
if (model.typeArguments && model.typeArguments.length > 0) {
|
||||
reflection.push(
|
||||
`<${model.typeArguments
|
||||
.map((typeArgument) => Handlebars.helpers.type.call(typeArgument))
|
||||
.join(", ")}\\>`
|
||||
)
|
||||
}
|
||||
return reflection.join("")
|
||||
}
|
||||
return emphasis
|
||||
? model.externalUrl
|
||||
? `[${`\`${model.name}\``}]( ${model.externalUrl} )`
|
||||
: `\`${model.name}\``
|
||||
: escapeChars(model.name)
|
||||
}
|
||||
|
||||
export function getArrayType(model: ArrayType, emphasis: boolean) {
|
||||
const arrayType = Handlebars.helpers.type.call(
|
||||
model.elementType,
|
||||
"none",
|
||||
emphasis
|
||||
)
|
||||
return model.elementType.type === "union"
|
||||
? `(${arrayType})[]`
|
||||
: `${arrayType}[]`
|
||||
}
|
||||
|
||||
export function getUnionType(model: UnionType, emphasis: boolean) {
|
||||
return model.types
|
||||
.map((unionType) =>
|
||||
Handlebars.helpers.type.call(unionType, "none", emphasis)
|
||||
)
|
||||
.join(` \\| `)
|
||||
}
|
||||
|
||||
export function getIntersectionType(model: IntersectionType) {
|
||||
return model.types
|
||||
.map((intersectionType) => Handlebars.helpers.type.call(intersectionType))
|
||||
.join(" & ")
|
||||
}
|
||||
|
||||
export function getTupleType(model: TupleType) {
|
||||
return `[${model.elements
|
||||
.map((element) => Handlebars.helpers.type.call(element))
|
||||
.join(", ")}]`
|
||||
}
|
||||
|
||||
export function getIntrinsicType(model: IntrinsicType, emphasis: boolean) {
|
||||
return emphasis ? `\`${model.name}\`` : escapeChars(model.name)
|
||||
}
|
||||
|
||||
export function getTypeOperatorType(model: TypeOperatorType) {
|
||||
return `${model.operator} ${Handlebars.helpers.type.call(model.target)}`
|
||||
}
|
||||
|
||||
export function getQueryType(model: QueryType) {
|
||||
return `typeof ${Handlebars.helpers.type.call(model.queryType)}`
|
||||
}
|
||||
|
||||
export function getInferredType(model: InferredType) {
|
||||
return `infer ${escapeChars(model.name)}`
|
||||
}
|
||||
|
||||
export function getUnknownType(model: UnknownType) {
|
||||
return escapeChars(model.name)
|
||||
}
|
||||
|
||||
export function getConditionalType(model: ConditionalType) {
|
||||
const md: string[] = []
|
||||
if (model.checkType) {
|
||||
md.push(Handlebars.helpers.type.call(model.checkType))
|
||||
}
|
||||
md.push("extends")
|
||||
if (model.extendsType) {
|
||||
md.push(Handlebars.helpers.type.call(model.extendsType))
|
||||
}
|
||||
md.push("?")
|
||||
if (model.trueType) {
|
||||
md.push(Handlebars.helpers.type.call(model.trueType))
|
||||
}
|
||||
md.push(":")
|
||||
if (model.falseType) {
|
||||
md.push(Handlebars.helpers.type.call(model.falseType))
|
||||
}
|
||||
return md.join(" ")
|
||||
}
|
||||
|
||||
export function getIndexAccessType(model: IndexedAccessType) {
|
||||
const md: string[] = []
|
||||
if (model.objectType) {
|
||||
md.push(Handlebars.helpers.type.call(model.objectType))
|
||||
}
|
||||
if (model.indexType) {
|
||||
md.push(`[${Handlebars.helpers.type.call(model.indexType)}]`)
|
||||
}
|
||||
return md.join("")
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
{{#if (sectionEnabled "comment")}}
|
||||
|
||||
{{#with comment}}
|
||||
|
||||
{{#if hasVisibleComponent}}
|
||||
|
||||
{{{comments this}}}
|
||||
|
||||
{{/if}}
|
||||
|
||||
{{/with}}
|
||||
|
||||
{{/if}}
|
||||
@@ -0,0 +1,5 @@
|
||||
{{#ifShowBreadcrumbs}}
|
||||
|
||||
{{{breadcrumbs}}}
|
||||
|
||||
{{/ifShowBreadcrumbs}}
|
||||
@@ -0,0 +1,3 @@
|
||||
{{ toc }}
|
||||
|
||||
{{> members}}
|
||||
Executable
+87
@@ -0,0 +1,87 @@
|
||||
{{{declarationTitle}}}
|
||||
|
||||
{{> comment}}
|
||||
|
||||
{{#if (sectionEnabled "member_declaration_typeParameters")}}
|
||||
|
||||
{{#if typeParameters}}
|
||||
|
||||
{{titleLevel 4}} Type parameters
|
||||
|
||||
{{#with typeParameters}}
|
||||
|
||||
{{{typeParameter}}}
|
||||
|
||||
{{/with}}
|
||||
|
||||
{{/if}}
|
||||
|
||||
{{/if}}
|
||||
|
||||
{{#if type.declaration}}
|
||||
|
||||
{{#if (sectionEnabled "member_declaration_indexSignature")}}
|
||||
|
||||
{{#if type.declaration.indexSignature}}
|
||||
|
||||
{{#with type.declaration.indexSignature}}
|
||||
|
||||
{{titleLevel 4}} Index signature
|
||||
|
||||
{{{indexSignatureTitle}}}
|
||||
|
||||
{{> comment}}
|
||||
|
||||
{{/with}}
|
||||
|
||||
{{/if}}
|
||||
|
||||
{{/if}}
|
||||
|
||||
{{#if (sectionEnabled "member_declaration_signatures")}}
|
||||
|
||||
{{#if type.declaration.signatures}}
|
||||
|
||||
{{#if type.declaration.children}}
|
||||
|
||||
{{titleLevel 4}} Call signature
|
||||
|
||||
{{else}}
|
||||
|
||||
{{titleLevel 4}} Type declaration
|
||||
|
||||
{{/if}}
|
||||
|
||||
{{#each type.declaration.signatures}}
|
||||
|
||||
{{> member.signature showSources=false }}
|
||||
|
||||
{{/each}}
|
||||
|
||||
{{/if}}
|
||||
|
||||
{{/if}}
|
||||
|
||||
{{#if (sectionEnabled "member_declaration_typeDeclaration")}}
|
||||
|
||||
{{#if type.declaration.children}}
|
||||
|
||||
{{#with type.declaration}}
|
||||
|
||||
{{titleLevel 4}} Type declaration
|
||||
|
||||
{{/with}}
|
||||
|
||||
{{#with type.declaration.children}}
|
||||
|
||||
{{{typeDeclarationMembers}}}
|
||||
|
||||
{{/with}}
|
||||
|
||||
{{/if}}
|
||||
|
||||
{{/if}}
|
||||
|
||||
{{/if}}
|
||||
|
||||
{{> member.sources}}
|
||||
Executable
+27
@@ -0,0 +1,27 @@
|
||||
{{#if getSignature}}
|
||||
|
||||
{{#if (sectionEnabled "member_getteSetter_getSignature")}}
|
||||
|
||||
{{#with getSignature}}
|
||||
|
||||
{{> member.signature accessor="get" showSources=true }}
|
||||
|
||||
{{/with}}
|
||||
|
||||
{{/if}}
|
||||
|
||||
{{/if}}
|
||||
|
||||
{{#if setSignature}}
|
||||
|
||||
{{#if (sectionEnabled "member_getteSetter_setSignature")}}
|
||||
|
||||
{{#with setSignature}}
|
||||
|
||||
{{> member.signature accessor="set" showSources=true }}
|
||||
|
||||
{{/with}}
|
||||
|
||||
{{/if}}
|
||||
|
||||
{{/if}}
|
||||
@@ -0,0 +1,61 @@
|
||||
{{#unless hasOwnDocument}}
|
||||
|
||||
{{#if name}}
|
||||
|
||||
{{titleLevel 3}} {{#ifNamedAnchors}}<a id="{{anchor}}" name="{{this.anchor}}"></a> {{/ifNamedAnchors}}{{ escape name }}
|
||||
|
||||
{{/if}}
|
||||
|
||||
{{/unless}}
|
||||
|
||||
{{#if signatures}}
|
||||
|
||||
{{#if (sectionEnabled "member_signatures")}}
|
||||
|
||||
{{#each signatures}}
|
||||
|
||||
{{> member.signature showSources=true }}
|
||||
|
||||
{{/each}}
|
||||
|
||||
{{/if}}
|
||||
|
||||
{{else}}
|
||||
|
||||
{{#if hasGetterOrSetter}}
|
||||
|
||||
{{#if (sectionEnabled "member_getterSetter")}}
|
||||
|
||||
{{> member.getterSetter}}
|
||||
|
||||
{{/if}}
|
||||
|
||||
{{else}}
|
||||
|
||||
{{#ifIsReference}}
|
||||
|
||||
{{#if (sectionEnabled "member_reference")}}
|
||||
|
||||
{{referenceMember}}
|
||||
|
||||
{{/if}}
|
||||
|
||||
{{else}}
|
||||
|
||||
{{#if (sectionEnabled "member_declaration")}}
|
||||
|
||||
{{> member.declaration}}
|
||||
|
||||
{{/if}}
|
||||
|
||||
{{/ifIsReference}}
|
||||
|
||||
{{/if}}
|
||||
|
||||
{{/if}}
|
||||
|
||||
{{#unless @last}}
|
||||
{{#unless hasOwnDocument}}
|
||||
___
|
||||
{{/unless}}
|
||||
{{/unless}}
|
||||
+147
@@ -0,0 +1,147 @@
|
||||
{{#if (sectionEnabled "member_signature_title")}}
|
||||
|
||||
{{{signatureTitle accessor}}}
|
||||
|
||||
{{/if}}
|
||||
|
||||
{{#if (sectionEnabled "member_signature_comment")}}
|
||||
|
||||
{{#with comment}}
|
||||
|
||||
{{#if hasVisibleComponent}}
|
||||
|
||||
{{{comments this true false}}}
|
||||
|
||||
{{/if}}
|
||||
|
||||
{{/with}}
|
||||
|
||||
{{/if}}
|
||||
|
||||
{{#if (sectionEnabled "member_signature_typeParameters")}}
|
||||
|
||||
{{#if typeParameters}}
|
||||
|
||||
{{#with typeParameters}}
|
||||
|
||||
{{{typeParameter}}}
|
||||
|
||||
{{/with}}
|
||||
|
||||
{{/if}}
|
||||
|
||||
{{/if}}
|
||||
|
||||
{{#if (sectionEnabled "member_signature_parameters")}}
|
||||
|
||||
{{#if parameters}}
|
||||
|
||||
{{#if showSources}}
|
||||
|
||||
{{titleLevel 4}} Parameters
|
||||
|
||||
{{else}}
|
||||
|
||||
{{titleLevel 5}} Parameters
|
||||
|
||||
{{/if}}
|
||||
|
||||
{{#with parameters}}
|
||||
|
||||
{{{parameter}}}
|
||||
|
||||
{{/with}}
|
||||
|
||||
{{/if}}
|
||||
|
||||
{{/if}}
|
||||
|
||||
{{#ifShowReturns}}
|
||||
|
||||
{{#if type}}
|
||||
|
||||
{{#if showSources}}
|
||||
|
||||
{{titleLevel 4}} Returns
|
||||
|
||||
{{else}}
|
||||
|
||||
{{titleLevel 5}} Returns
|
||||
|
||||
{{/if}}
|
||||
|
||||
{{#if (getFormattingOption "showReturnSignature")}}
|
||||
|
||||
{{#with type}}
|
||||
|
||||
{{{type 'all'}}}
|
||||
|
||||
{{/with}}
|
||||
|
||||
{{/if}}
|
||||
|
||||
{{#with comment}}
|
||||
|
||||
{{{returns this}}}
|
||||
|
||||
{{/with}}
|
||||
|
||||
{{#with type}}
|
||||
|
||||
{{#if (sectionEnabled "member_signature_declarationSignatures")}}
|
||||
|
||||
{{#if declaration.signatures}}
|
||||
|
||||
{{#each declaration.signatures}}
|
||||
|
||||
{{> member.signature showSources=false }}
|
||||
|
||||
{{/each}}
|
||||
|
||||
{{/if}}
|
||||
|
||||
{{/if}}
|
||||
|
||||
{{#if (sectionEnabled "member_signature_declarationChildren")}}
|
||||
|
||||
{{#if declaration.children}}
|
||||
|
||||
{{#with declaration.children}}
|
||||
|
||||
{{{typeDeclarationMembers}}}
|
||||
|
||||
{{/with}}
|
||||
|
||||
{{/if}}
|
||||
|
||||
{{/if}}
|
||||
|
||||
{{/with}}
|
||||
|
||||
{{/if}}
|
||||
|
||||
{{/ifShowReturns}}
|
||||
|
||||
{{#if (sectionEnabled "member_signature_comment")}}
|
||||
|
||||
{{#with comment}}
|
||||
|
||||
{{#if hasVisibleComponent}}
|
||||
|
||||
{{{comments this false true 4}}}
|
||||
|
||||
{{/if}}
|
||||
|
||||
{{/with}}
|
||||
|
||||
{{/if}}
|
||||
|
||||
{{#if (sectionEnabled "member_signature_sources")}}
|
||||
|
||||
{{#if showSources}}
|
||||
|
||||
{{> member.sources}}
|
||||
|
||||
{{/if}}
|
||||
|
||||
{{/if}}
|
||||
Executable
+71
@@ -0,0 +1,71 @@
|
||||
{{#if (sectionEnabled "member_sources_implementationOf")}}
|
||||
|
||||
{{#if implementationOf}}
|
||||
|
||||
{{titleLevel 4}} Implementation of
|
||||
|
||||
{{#with implementationOf}}
|
||||
|
||||
{{typeAndParent}}
|
||||
|
||||
{{/with}}
|
||||
|
||||
{{/if}}
|
||||
|
||||
{{/if}}
|
||||
|
||||
{{#if (sectionEnabled "member_sources_inheritedFrom")}}
|
||||
|
||||
{{#if inheritedFrom}}
|
||||
|
||||
{{titleLevel 4}} Inherited from
|
||||
|
||||
{{#with inheritedFrom}}
|
||||
|
||||
{{{typeAndParent}}}
|
||||
|
||||
{{/with}}
|
||||
|
||||
{{/if}}
|
||||
|
||||
{{/if}}
|
||||
|
||||
{{#if (sectionEnabled "member_sources_overrides")}}
|
||||
|
||||
{{#if overwrites}}
|
||||
|
||||
{{titleLevel 4}} Overrides
|
||||
|
||||
{{#with overwrites}}
|
||||
|
||||
{{typeAndParent}}
|
||||
|
||||
{{/with}}
|
||||
|
||||
{{/if}}
|
||||
|
||||
{{/if}}
|
||||
|
||||
{{#if (sectionEnabled "member_sources_definedIn")}}
|
||||
|
||||
{{#if sources}}
|
||||
|
||||
{{titleLevel 4}} Defined in
|
||||
|
||||
{{#each sources}}
|
||||
|
||||
{{#if url}}
|
||||
|
||||
[{{fileName}}:{{line}}]({{url}})
|
||||
|
||||
{{else}}
|
||||
|
||||
{{fileName}}:{{line}}
|
||||
|
||||
{{/if}}
|
||||
|
||||
{{/each}}
|
||||
|
||||
{{/if}}
|
||||
|
||||
{{/if}}
|
||||
Executable
+41
@@ -0,0 +1,41 @@
|
||||
{{#if (sectionEnabled "members_group_categories")}}
|
||||
|
||||
{{#if categories}}
|
||||
|
||||
{{#each categories}}
|
||||
|
||||
{{#unless @first}}
|
||||
___
|
||||
{{/unless}}
|
||||
|
||||
{{#unless (getFormattingOption "expandMembers")}}
|
||||
|
||||
## {{title}} {{../title}}
|
||||
|
||||
{{/unless}}
|
||||
|
||||
{{#each children}}
|
||||
|
||||
{{> member}}
|
||||
|
||||
{{/each}}
|
||||
|
||||
{{/each}}
|
||||
|
||||
{{else}}
|
||||
|
||||
{{#unless (getFormattingOption "expandMembers")}}
|
||||
|
||||
## {{title}}
|
||||
|
||||
{{/unless}}
|
||||
|
||||
{{#each children}}
|
||||
|
||||
{{> member}}
|
||||
|
||||
{{/each}}
|
||||
|
||||
{{/if}}
|
||||
|
||||
{{/if}}
|
||||
@@ -0,0 +1,43 @@
|
||||
{{#if (sectionEnabled "members_categories")}}
|
||||
|
||||
{{#if categories}}
|
||||
|
||||
{{#each categories}}
|
||||
|
||||
{{#unless allChildrenHaveOwnDocument}}
|
||||
|
||||
{{#unless (getFormattingOption "expandMembers")}}
|
||||
|
||||
## {{title}}
|
||||
|
||||
{{/unless}}
|
||||
|
||||
{{#each children}}
|
||||
|
||||
{{#unless hasOwnDocument}}
|
||||
|
||||
{{> member}}
|
||||
|
||||
{{/unless}}
|
||||
|
||||
{{/each}}
|
||||
|
||||
{{/unless}}
|
||||
|
||||
{{/each}}
|
||||
|
||||
{{else}}
|
||||
|
||||
{{#each groups}}
|
||||
|
||||
{{#unless allChildrenHaveOwnDocument}}
|
||||
|
||||
{{> members.group}}
|
||||
|
||||
{{/unless}}
|
||||
|
||||
{{/each}}
|
||||
|
||||
{{/if}}
|
||||
|
||||
{{/if}}
|
||||
@@ -0,0 +1,13 @@
|
||||
{{#ifShowPageTitle}}
|
||||
|
||||
# {{{reflectionTitle true}}}
|
||||
|
||||
{{/ifShowPageTitle}}
|
||||
|
||||
{{{getFormattingOption "reflectionDescription"}}}
|
||||
|
||||
{{#if (sectionEnabled "title_reflectionPath")}}
|
||||
|
||||
{{{reflectionPath}}}
|
||||
|
||||
{{/if}}
|
||||
@@ -0,0 +1,7 @@
|
||||
{{> header}}
|
||||
|
||||
{{#with model.readme}}
|
||||
|
||||
{{{comment this}}}
|
||||
|
||||
{{/with}}
|
||||
+127
@@ -0,0 +1,127 @@
|
||||
{{> header}}
|
||||
|
||||
{{> title}}
|
||||
|
||||
{{#with model}}
|
||||
|
||||
{{#if (sectionEnabled "reflection_comment")}}
|
||||
|
||||
{{#if hasComment}}
|
||||
|
||||
{{> comment}}
|
||||
|
||||
{{/if}}
|
||||
|
||||
{{/if}}
|
||||
|
||||
{{/with}}
|
||||
|
||||
{{#if (sectionEnabled "reflection_typeParameters")}}
|
||||
|
||||
{{#if model.typeParameters}}
|
||||
|
||||
## Type parameters
|
||||
|
||||
{{#with model.typeParameters}}
|
||||
|
||||
{{{typeParameter}}}
|
||||
|
||||
{{/with}}
|
||||
|
||||
{{/if}}
|
||||
|
||||
{{/if}}
|
||||
|
||||
{{#if (sectionEnabled "reflection_hierarchy")}}
|
||||
|
||||
{{#ifShowTypeHierarchy}}
|
||||
|
||||
## Hierarchy
|
||||
|
||||
{{#with model.typeHierarchy}}
|
||||
|
||||
{{{hierarchy 0}}}
|
||||
|
||||
{{/with}}
|
||||
|
||||
{{/ifShowTypeHierarchy}}
|
||||
|
||||
{{/if}}
|
||||
|
||||
{{#if (sectionEnabled "reflection_implements")}}
|
||||
|
||||
{{#if model.implementedTypes}}
|
||||
|
||||
## Implements
|
||||
|
||||
{{#each model.implementedTypes}}
|
||||
- {{{type}}}
|
||||
{{/each}}
|
||||
|
||||
{{/if}}
|
||||
|
||||
{{/if}}
|
||||
|
||||
{{#if (sectionEnabled "reflection_implementedBy")}}
|
||||
|
||||
{{#if model.implementedBy}}
|
||||
|
||||
## Implemented by
|
||||
|
||||
{{#each model.implementedBy}}
|
||||
- {{{type}}}
|
||||
{{/each}}
|
||||
|
||||
{{/if}}
|
||||
|
||||
{{/if}}
|
||||
|
||||
{{#if (sectionEnabled "reflection_callable")}}
|
||||
|
||||
{{#if model.signatures}}
|
||||
|
||||
## Callable
|
||||
|
||||
{{#with model}}
|
||||
|
||||
{{#each signatures}}
|
||||
|
||||
### {{name}}
|
||||
|
||||
{{> member.signature showSources=true }}
|
||||
|
||||
{{/each}}
|
||||
|
||||
{{/with}}
|
||||
|
||||
{{/if}}
|
||||
|
||||
{{/if}}
|
||||
|
||||
{{#if (sectionEnabled "reflection_indexable")}}
|
||||
|
||||
{{#if model.indexSignature}}
|
||||
|
||||
## Indexable
|
||||
|
||||
{{#with model}}
|
||||
|
||||
{{#with indexSignature}}
|
||||
|
||||
{{{indexSignatureTitle}}}
|
||||
|
||||
{{> comment}}
|
||||
|
||||
{{/with}}
|
||||
|
||||
{{/with}}
|
||||
|
||||
{{/if}}
|
||||
|
||||
{{/if}}
|
||||
|
||||
{{#with model}}
|
||||
|
||||
{{> main}}
|
||||
|
||||
{{/with}}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
{{> header}}
|
||||
|
||||
{{> title}}
|
||||
|
||||
{{#with model}}
|
||||
|
||||
{{> member}}
|
||||
|
||||
{{/with}}
|
||||
@@ -0,0 +1,454 @@
|
||||
import * as path from "path"
|
||||
import {
|
||||
ContainerReflection,
|
||||
DeclarationReflection,
|
||||
PageEvent,
|
||||
ProjectReflection,
|
||||
Reflection,
|
||||
ReflectionGroup,
|
||||
ReflectionKind,
|
||||
RenderTemplate,
|
||||
Renderer,
|
||||
RendererEvent,
|
||||
Theme,
|
||||
UrlMapping,
|
||||
} from "typedoc"
|
||||
import { getKindPlural } from "./groups"
|
||||
import {
|
||||
indexTemplate,
|
||||
reflectionMemberTemplate,
|
||||
reflectionTemplate,
|
||||
registerHelpers,
|
||||
registerPartials,
|
||||
} from "./render-utils"
|
||||
import { formatContents } from "./utils"
|
||||
import {
|
||||
FormattingOptionType,
|
||||
FormattingOptionsType,
|
||||
Mapping,
|
||||
NavigationItem,
|
||||
ObjectLiteralDeclarationStyle,
|
||||
} from "./types"
|
||||
|
||||
export class MarkdownTheme extends Theme {
|
||||
allReflectionsHaveOwnDocument!: boolean
|
||||
entryDocument: string
|
||||
entryPoints!: string[]
|
||||
filenameSeparator!: string
|
||||
hideBreadcrumbs!: boolean
|
||||
hideInPageTOC!: boolean
|
||||
hidePageTitle!: boolean
|
||||
hideMembersSymbol!: boolean
|
||||
includes!: string
|
||||
indexTitle!: string
|
||||
mediaDirectory!: string
|
||||
namedAnchors!: boolean
|
||||
readme!: string
|
||||
out!: string
|
||||
publicPath!: string
|
||||
preserveAnchorCasing!: boolean
|
||||
objectLiteralTypeDeclarationStyle: ObjectLiteralDeclarationStyle
|
||||
formattingOptions: FormattingOptionsType
|
||||
|
||||
project?: ProjectReflection
|
||||
reflection?: DeclarationReflection
|
||||
location!: string
|
||||
anchorMap: Record<string, string[]> = {}
|
||||
|
||||
static URL_PREFIX = /^(http|ftp)s?:\/\//
|
||||
|
||||
constructor(renderer: Renderer) {
|
||||
super(renderer)
|
||||
|
||||
// prettier-ignore
|
||||
this.allReflectionsHaveOwnDocument = this.getOption("allReflectionsHaveOwnDocument") as boolean
|
||||
this.entryDocument = this.getOption("entryDocument") as string
|
||||
this.entryPoints = this.getOption("entryPoints") as string[]
|
||||
this.filenameSeparator = this.getOption("filenameSeparator") as string
|
||||
this.hideBreadcrumbs = this.getOption("hideBreadcrumbs") as boolean
|
||||
this.hideInPageTOC = this.getOption("hideInPageTOC") as boolean
|
||||
this.hidePageTitle = this.getOption("hidePageTitle") as boolean
|
||||
this.hideMembersSymbol = this.getOption("hideMembersSymbol") as boolean
|
||||
this.includes = this.getOption("includes") as string
|
||||
this.indexTitle = this.getOption("indexTitle") as string
|
||||
this.mediaDirectory = this.getOption("media") as string
|
||||
this.namedAnchors = this.getOption("namedAnchors") as boolean
|
||||
this.readme = this.getOption("readme") as string
|
||||
this.out = this.getOption("out") as string
|
||||
this.publicPath = this.getOption("publicPath") as string
|
||||
this.preserveAnchorCasing = this.getOption(
|
||||
"preserveAnchorCasing"
|
||||
) as boolean
|
||||
this.objectLiteralTypeDeclarationStyle = this.getOption(
|
||||
"objectLiteralTypeDeclarationStyle"
|
||||
) as ObjectLiteralDeclarationStyle
|
||||
this.formattingOptions = this.getOption(
|
||||
"formatting"
|
||||
) as FormattingOptionsType
|
||||
|
||||
this.listenTo(this.owner, {
|
||||
[RendererEvent.BEGIN]: this.onBeginRenderer,
|
||||
[PageEvent.BEGIN]: this.onBeginPage,
|
||||
})
|
||||
|
||||
registerPartials()
|
||||
registerHelpers(this)
|
||||
}
|
||||
|
||||
render(
|
||||
page: PageEvent<Reflection>,
|
||||
template: RenderTemplate<PageEvent<Reflection>>
|
||||
): string {
|
||||
return formatContents(template(page) as string)
|
||||
}
|
||||
|
||||
getOption(key: string) {
|
||||
return this.application.options.getValue(key)
|
||||
}
|
||||
|
||||
getUrls(project: ProjectReflection) {
|
||||
const urls: UrlMapping[] = []
|
||||
const noReadmeFile = this.readme.endsWith("none")
|
||||
if (noReadmeFile) {
|
||||
project.url = this.entryDocument
|
||||
urls.push(
|
||||
new UrlMapping(
|
||||
this.entryDocument,
|
||||
project,
|
||||
this.getReflectionTemplate()
|
||||
)
|
||||
)
|
||||
} else {
|
||||
project.url = this.globalsFile
|
||||
urls.push(
|
||||
new UrlMapping(this.globalsFile, project, this.getReflectionTemplate())
|
||||
)
|
||||
urls.push(
|
||||
new UrlMapping(this.entryDocument, project, this.getIndexTemplate())
|
||||
)
|
||||
}
|
||||
project.children?.forEach((child: Reflection) => {
|
||||
if (child instanceof DeclarationReflection) {
|
||||
this.buildUrls(child as DeclarationReflection, urls)
|
||||
}
|
||||
})
|
||||
return urls
|
||||
}
|
||||
|
||||
buildUrls(
|
||||
reflection: DeclarationReflection,
|
||||
urls: UrlMapping[]
|
||||
): UrlMapping[] {
|
||||
const mapping = this.mappings.find((mapping) =>
|
||||
reflection.kindOf(mapping.kind)
|
||||
)
|
||||
if (mapping) {
|
||||
if (!reflection.url || !MarkdownTheme.URL_PREFIX.test(reflection.url)) {
|
||||
const url = this.toUrl(mapping, reflection)
|
||||
urls.push(new UrlMapping(url, reflection, mapping.template))
|
||||
reflection.url = url
|
||||
reflection.hasOwnDocument = true
|
||||
}
|
||||
|
||||
for (const child of reflection.children || []) {
|
||||
if (mapping.isLeaf) {
|
||||
this.applyAnchorUrl(child, reflection)
|
||||
} else {
|
||||
this.buildUrls(child, urls)
|
||||
}
|
||||
}
|
||||
} else if (reflection.parent) {
|
||||
this.applyAnchorUrl(reflection, reflection.parent, true)
|
||||
}
|
||||
return urls
|
||||
}
|
||||
|
||||
toUrl(mapping: Mapping, reflection: DeclarationReflection) {
|
||||
return mapping.directory + "/" + this.getUrl(reflection) + ".md"
|
||||
}
|
||||
|
||||
getUrl(reflection: Reflection, relative?: Reflection): string {
|
||||
let url = reflection.getAlias()
|
||||
|
||||
if (
|
||||
reflection.parent &&
|
||||
reflection.parent !== relative &&
|
||||
!(reflection.parent instanceof ProjectReflection)
|
||||
) {
|
||||
url =
|
||||
this.getUrl(reflection.parent, relative) + this.filenameSeparator + url
|
||||
}
|
||||
|
||||
return url.replace(/^_/, "")
|
||||
}
|
||||
|
||||
applyAnchorUrl(
|
||||
reflection: Reflection,
|
||||
container: Reflection,
|
||||
isSymbol = false
|
||||
) {
|
||||
if (
|
||||
container.url &&
|
||||
(!reflection.url || !MarkdownTheme.URL_PREFIX.test(reflection.url))
|
||||
) {
|
||||
const reflectionId = this.preserveAnchorCasing
|
||||
? reflection.name
|
||||
: reflection.name.toLowerCase()
|
||||
|
||||
if (isSymbol) {
|
||||
this.anchorMap[container.url]
|
||||
? this.anchorMap[container.url].push(reflectionId)
|
||||
: (this.anchorMap[container.url] = [reflectionId])
|
||||
}
|
||||
|
||||
const count = this.anchorMap[container.url]?.filter(
|
||||
(id) => id === reflectionId
|
||||
)?.length
|
||||
|
||||
const anchor = this.toAnchorRef(
|
||||
reflectionId + (count > 1 ? "-" + (count - 1).toString() : "")
|
||||
)
|
||||
|
||||
reflection.url = container.url + "#" + anchor
|
||||
reflection.anchor = anchor
|
||||
reflection.hasOwnDocument = false
|
||||
}
|
||||
reflection.traverse((child) => {
|
||||
if (child instanceof DeclarationReflection) {
|
||||
this.applyAnchorUrl(child, container)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
toAnchorRef(reflectionId: string) {
|
||||
return reflectionId
|
||||
}
|
||||
|
||||
getRelativeUrl(absolute: string) {
|
||||
if (MarkdownTheme.URL_PREFIX.test(absolute)) {
|
||||
return absolute
|
||||
} else {
|
||||
const relative = path.relative(
|
||||
path.dirname(this.location),
|
||||
path.dirname(absolute)
|
||||
)
|
||||
return path.join(relative, path.basename(absolute)).replace(/\\/g, "/")
|
||||
}
|
||||
}
|
||||
|
||||
getReflectionTemplate() {
|
||||
return (pageEvent: PageEvent<ContainerReflection>) => {
|
||||
return reflectionTemplate(pageEvent, {
|
||||
allowProtoMethodsByDefault: true,
|
||||
allowProtoPropertiesByDefault: true,
|
||||
data: { theme: this },
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
getReflectionMemberTemplate() {
|
||||
return (pageEvent: PageEvent<ContainerReflection>) => {
|
||||
return reflectionMemberTemplate(pageEvent, {
|
||||
allowProtoMethodsByDefault: true,
|
||||
allowProtoPropertiesByDefault: true,
|
||||
data: { theme: this },
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
getIndexTemplate() {
|
||||
return (pageEvent: PageEvent<ContainerReflection>) => {
|
||||
return indexTemplate(pageEvent, {
|
||||
allowProtoMethodsByDefault: true,
|
||||
allowProtoPropertiesByDefault: true,
|
||||
data: { theme: this },
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
getNavigation(project: ProjectReflection) {
|
||||
const urls = this.getUrls(project)
|
||||
|
||||
const getUrlMapping = (name: string) => {
|
||||
if (!name) {
|
||||
return ""
|
||||
}
|
||||
return urls.find((url) => url.model.name === name)
|
||||
}
|
||||
|
||||
const createNavigationItem = (
|
||||
title: string,
|
||||
url: string | undefined,
|
||||
isLabel: boolean,
|
||||
children: NavigationItem[] = []
|
||||
) => {
|
||||
const navigationItem = new NavigationItem(title, url)
|
||||
navigationItem.isLabel = isLabel
|
||||
navigationItem.children = children
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const { reflection, parent, ...filteredNavigationItem } = navigationItem
|
||||
return filteredNavigationItem as NavigationItem
|
||||
}
|
||||
const navigation = createNavigationItem(project.name, undefined, false)
|
||||
const hasReadme = !this.readme.endsWith("none")
|
||||
if (hasReadme) {
|
||||
navigation.children?.push(
|
||||
createNavigationItem("Readme", this.entryDocument, false)
|
||||
)
|
||||
}
|
||||
if (this.entryPoints.length === 1) {
|
||||
navigation.children?.push(
|
||||
createNavigationItem(
|
||||
"Exports",
|
||||
hasReadme ? this.globalsFile : this.entryDocument,
|
||||
false
|
||||
)
|
||||
)
|
||||
}
|
||||
this.mappings.forEach((mapping) => {
|
||||
const kind = mapping.kind[0]
|
||||
const items = project.getReflectionsByKind(kind)
|
||||
if (items.length > 0) {
|
||||
const children = items
|
||||
.map((item) => {
|
||||
const urlMapping = getUrlMapping(item.name) || ""
|
||||
return createNavigationItem(
|
||||
item.getFullName(),
|
||||
typeof urlMapping === "string" ? urlMapping : urlMapping.url,
|
||||
true
|
||||
)
|
||||
})
|
||||
.sort((a, b) => {
|
||||
return a.title > b.title ? 1 : -1
|
||||
})
|
||||
const group = createNavigationItem(
|
||||
getKindPlural(kind),
|
||||
undefined,
|
||||
true,
|
||||
children
|
||||
)
|
||||
navigation.children?.push(group)
|
||||
}
|
||||
})
|
||||
return navigation
|
||||
}
|
||||
|
||||
get mappings(): Mapping[] {
|
||||
return [
|
||||
{
|
||||
kind: [ReflectionKind.Module],
|
||||
isLeaf: false,
|
||||
directory: "modules",
|
||||
template: this.getReflectionTemplate(),
|
||||
},
|
||||
{
|
||||
kind: [ReflectionKind.Namespace],
|
||||
isLeaf: false,
|
||||
directory: "modules",
|
||||
template: this.getReflectionTemplate(),
|
||||
},
|
||||
{
|
||||
kind: [ReflectionKind.Enum],
|
||||
isLeaf: false,
|
||||
directory: "enums",
|
||||
template: this.getReflectionTemplate(),
|
||||
},
|
||||
{
|
||||
kind: [ReflectionKind.Class],
|
||||
isLeaf: false,
|
||||
directory: "classes",
|
||||
template: this.getReflectionTemplate(),
|
||||
},
|
||||
{
|
||||
kind: [ReflectionKind.Interface],
|
||||
isLeaf: false,
|
||||
directory: "interfaces",
|
||||
template: this.getReflectionTemplate(),
|
||||
},
|
||||
...(this.allReflectionsHaveOwnDocument
|
||||
? [
|
||||
{
|
||||
kind: [ReflectionKind.TypeAlias],
|
||||
isLeaf: true,
|
||||
directory: "types",
|
||||
template: this.getReflectionMemberTemplate(),
|
||||
},
|
||||
{
|
||||
kind: [ReflectionKind.Variable],
|
||||
isLeaf: true,
|
||||
directory: "variables",
|
||||
template: this.getReflectionMemberTemplate(),
|
||||
},
|
||||
{
|
||||
kind: [ReflectionKind.Function],
|
||||
isLeaf: true,
|
||||
directory: "functions",
|
||||
template: this.getReflectionMemberTemplate(),
|
||||
},
|
||||
]
|
||||
: []),
|
||||
]
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggered before the renderer starts rendering a project.
|
||||
*
|
||||
* @param event An event object describing the current render operation.
|
||||
*/
|
||||
protected onBeginRenderer(event: RendererEvent) {
|
||||
this.project = event.project
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggered before a document will be rendered.
|
||||
*
|
||||
* @param page An event object describing the current render operation.
|
||||
*/
|
||||
protected onBeginPage(page: PageEvent) {
|
||||
this.location = page.url
|
||||
this.reflection =
|
||||
page.model instanceof DeclarationReflection ? page.model : undefined
|
||||
const options = this.getFormattingOptionsForLocation()
|
||||
if (this.reflection && this.reflection.groups) {
|
||||
// filter out unwanted groups
|
||||
const tempGroups: ReflectionGroup[] = []
|
||||
this.reflection.groups.forEach((reflectionGroup) => {
|
||||
if (
|
||||
!options.reflectionGroups ||
|
||||
!(reflectionGroup.title in options.reflectionGroups) ||
|
||||
options.reflectionGroups[reflectionGroup.title]
|
||||
) {
|
||||
tempGroups.push(reflectionGroup)
|
||||
}
|
||||
})
|
||||
|
||||
this.reflection.groups = tempGroups
|
||||
}
|
||||
}
|
||||
|
||||
get globalsFile() {
|
||||
return "modules.md"
|
||||
}
|
||||
|
||||
getFormattingOptionsForLocation(): FormattingOptionType {
|
||||
if (!this.location) {
|
||||
return {}
|
||||
}
|
||||
|
||||
const optionKey =
|
||||
Object.keys(this.formattingOptions).find((key) => {
|
||||
if (key === "*") {
|
||||
return false
|
||||
}
|
||||
|
||||
const keyPattern = new RegExp(key)
|
||||
if (keyPattern.test(this.location)) {
|
||||
return true
|
||||
}
|
||||
}) || "*"
|
||||
|
||||
return optionKey in this.formattingOptions
|
||||
? this.formattingOptions[optionKey]
|
||||
: {}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
import {
|
||||
ContainerReflection,
|
||||
DeclarationReflection,
|
||||
PageEvent,
|
||||
ParameterReflection,
|
||||
Reflection,
|
||||
ReflectionKind,
|
||||
TypeParameterReflection,
|
||||
} from "typedoc"
|
||||
|
||||
export type ParameterStyle = "table" | "list"
|
||||
|
||||
export type ReflectionTitleOptions = {
|
||||
typeParameters?: boolean
|
||||
kind?: boolean
|
||||
}
|
||||
|
||||
export type ObjectLiteralDeclarationStyle = "table" | "list"
|
||||
|
||||
export type SectionKey =
|
||||
| "comment"
|
||||
| "member_declaration_typeParameters"
|
||||
| "member_declaration_indexSignature"
|
||||
| "member_declaration_signatures"
|
||||
| "member_declaration_typeDeclaration"
|
||||
| "member_getteSetter_getSignature"
|
||||
| "member_getteSetter_setSignature"
|
||||
| "member_signatures"
|
||||
| "member_getterSetter"
|
||||
| "member_reference"
|
||||
| "member_declaration"
|
||||
| "member_signature_title"
|
||||
| "member_signature_comment"
|
||||
| "member_signature_typeParameters"
|
||||
| "member_signature_parameters"
|
||||
| "showReturnSignature"
|
||||
| "member_signature_declarationSignatures"
|
||||
| "member_signature_declarationChildren"
|
||||
| "member_signature_comment"
|
||||
| "member_signature_sources"
|
||||
| "member_sources_implementationOf"
|
||||
| "member_sources_inheritedFrom"
|
||||
| "member_sources_overrides"
|
||||
| "member_sources_definedIn"
|
||||
| "members_group_categories"
|
||||
| "members_categories"
|
||||
| "title_reflectionPath"
|
||||
| "reflection_comment"
|
||||
| "reflection_typeParameters"
|
||||
| "reflection_hierarchy"
|
||||
| "reflection_implements"
|
||||
| "reflection_implementedBy"
|
||||
| "reflection_callable"
|
||||
| "reflection_indexable"
|
||||
|
||||
export type FormattingOptionType = {
|
||||
sections?: {
|
||||
[k in SectionKey]: boolean
|
||||
}
|
||||
reflectionGroups?: {
|
||||
[k: string]: boolean
|
||||
}
|
||||
reflectionTitle?: {
|
||||
kind: boolean
|
||||
typeParameters: boolean
|
||||
suffix?: string
|
||||
}
|
||||
reflectionDescription?: string
|
||||
expandMembers?: boolean
|
||||
showCommentsAsHeader?: boolean
|
||||
parameterStyle?: ParameterStyle
|
||||
showReturnSignature?: boolean
|
||||
}
|
||||
|
||||
export type FormattingOptionsType = {
|
||||
[k: string]: FormattingOptionType
|
||||
}
|
||||
|
||||
export type ReflectionParameterType =
|
||||
| ParameterReflection
|
||||
| DeclarationReflection
|
||||
| TypeParameterReflection
|
||||
|
||||
export type Mapping = {
|
||||
kind: ReflectionKind[]
|
||||
isLeaf: boolean
|
||||
directory: string
|
||||
template: (pageEvent: PageEvent<ContainerReflection>) => string
|
||||
}
|
||||
|
||||
export class NavigationItem {
|
||||
title: string
|
||||
url: string
|
||||
dedicatedUrls?: string[]
|
||||
parent?: NavigationItem
|
||||
children?: NavigationItem[]
|
||||
isLabel?: boolean
|
||||
isVisible?: boolean
|
||||
isCurrent?: boolean
|
||||
isModules?: boolean
|
||||
isInPath?: boolean
|
||||
reflection?: Reflection
|
||||
|
||||
constructor(
|
||||
title?: string,
|
||||
url?: string,
|
||||
parent?: NavigationItem,
|
||||
reflection?: Reflection
|
||||
) {
|
||||
this.title = title || ""
|
||||
this.url = url || ""
|
||||
this.parent = parent
|
||||
this.reflection = reflection
|
||||
|
||||
if (!url) {
|
||||
this.isLabel = true
|
||||
}
|
||||
|
||||
if (this.parent) {
|
||||
if (!this.parent.children) {
|
||||
this.parent.children = []
|
||||
}
|
||||
this.parent.children.push(this)
|
||||
}
|
||||
}
|
||||
|
||||
static create(
|
||||
reflection: Reflection,
|
||||
parent?: NavigationItem,
|
||||
useShortNames?: boolean
|
||||
) {
|
||||
let name: string
|
||||
if (useShortNames || (parent && parent.parent)) {
|
||||
name = reflection.name
|
||||
} else {
|
||||
name = reflection.getFullName()
|
||||
}
|
||||
|
||||
name = name.trim()
|
||||
|
||||
return new NavigationItem(name, reflection.url, parent, reflection)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
import {
|
||||
DeclarationReflection,
|
||||
ParameterReflection,
|
||||
ProjectReflection,
|
||||
Reflection,
|
||||
ReflectionKind,
|
||||
SignatureReflection,
|
||||
} from "typedoc"
|
||||
|
||||
export function formatContents(contents: string) {
|
||||
return (
|
||||
contents
|
||||
.replace(/[\r\n]{3,}/g, "\n\n")
|
||||
.replace(/!spaces/g, "")
|
||||
.replace(/^\s+|\s+$/g, "") + "\n"
|
||||
)
|
||||
}
|
||||
|
||||
export function escapeChars(str: string) {
|
||||
return str
|
||||
.replace(/>/g, "\\>")
|
||||
.replace(/_/g, "\\_")
|
||||
.replace(/`/g, "\\`")
|
||||
.replace(/\|/g, "\\|")
|
||||
}
|
||||
|
||||
export function memberSymbol(
|
||||
reflection: DeclarationReflection | ParameterReflection | SignatureReflection
|
||||
) {
|
||||
const isStatic = reflection.flags && reflection.flags.isStatic
|
||||
|
||||
if (reflection.kind === ReflectionKind.CallSignature) {
|
||||
return "▸"
|
||||
}
|
||||
if (reflection.kind === ReflectionKind.TypeAlias) {
|
||||
return "Ƭ"
|
||||
}
|
||||
if (reflection.kind === ReflectionKind.Property && isStatic) {
|
||||
return "▪"
|
||||
}
|
||||
return "•"
|
||||
}
|
||||
|
||||
export function spaces(length: number) {
|
||||
return `!spaces${[...Array(length)].map(() => " ").join("")}`
|
||||
}
|
||||
|
||||
export function stripComments(str: string) {
|
||||
return str
|
||||
.replace(/(?:\/\*(?:[\s\S]*?)\*\/)|(?:^\s*\/\/(?:.*)$)/g, " ")
|
||||
.replace(/\n/g, "")
|
||||
.replace(/^\s+|\s+$|(\s)+/g, "$1")
|
||||
}
|
||||
|
||||
export function stripLineBreaks(str: string) {
|
||||
return str
|
||||
? str
|
||||
.replace(/\n/g, " ")
|
||||
.replace(/\r/g, " ")
|
||||
.replace(/\t/g, " ")
|
||||
.replace(/[\s]{2,}/g, " ")
|
||||
.trim()
|
||||
: ""
|
||||
}
|
||||
|
||||
export function camelToTitleCase(text: string) {
|
||||
return (
|
||||
text.substring(0, 1).toUpperCase() +
|
||||
text.substring(1).replace(/[a-z][A-Z]/g, (x) => `${x[0]} ${x[1]}`)
|
||||
)
|
||||
}
|
||||
|
||||
export function getDisplayName(refl: Reflection): string {
|
||||
let version = ""
|
||||
if (
|
||||
(refl instanceof DeclarationReflection ||
|
||||
refl instanceof ProjectReflection) &&
|
||||
refl.packageVersion
|
||||
) {
|
||||
version = ` - v${refl.packageVersion}`
|
||||
}
|
||||
return `${refl.name}${version}`
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
import * as Handlebars from "handlebars"
|
||||
import { PageEvent } from "typedoc/dist/lib/output/events"
|
||||
|
||||
export interface FrontMatterVars {
|
||||
[key: string]: string | number | boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepends YAML block to a string
|
||||
* @param contents - the string to prepend
|
||||
* @param vars - object of required front matter variables
|
||||
*/
|
||||
export const prependYAML = (contents: string, vars: FrontMatterVars) => {
|
||||
return contents
|
||||
.replace(/^/, toYAML(vars) + "\n\n")
|
||||
.replace(/[\r\n]{3,}/g, "\n\n")
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the page title as rendered in the document h1(# title)
|
||||
* @param page
|
||||
*/
|
||||
export const getPageTitle = (page: PageEvent) => {
|
||||
return Handlebars.helpers.reflectionTitle.call(page, false)
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts YAML object to a YAML string
|
||||
* @param vars
|
||||
*/
|
||||
const toYAML = (vars: FrontMatterVars) => {
|
||||
const yaml = `---
|
||||
${Object.entries(vars)
|
||||
.map(
|
||||
([key, value]) =>
|
||||
`${key}: ${
|
||||
typeof value === "string" ? `"${escapeString(value)}"` : value
|
||||
}`
|
||||
)
|
||||
.join("\n")}
|
||||
---`
|
||||
return yaml
|
||||
}
|
||||
|
||||
// prettier-ignore
|
||||
const escapeString = (str: string) => str.replace(/"/g, "\\\"")
|
||||
@@ -0,0 +1,36 @@
|
||||
import { ReflectionKind } from "typedoc"
|
||||
import { ReflectionParameterType } from "../types"
|
||||
|
||||
export function flattenParams(
|
||||
current: ReflectionParameterType
|
||||
): ReflectionParameterType[] {
|
||||
if (!current.type || !("declaration" in current.type)) {
|
||||
return []
|
||||
}
|
||||
return (
|
||||
current.type?.declaration?.children?.reduce(
|
||||
(acc: ReflectionParameterType[], child: ReflectionParameterType) => {
|
||||
const childObj = {
|
||||
...child,
|
||||
name: `${current.name}.${child.name}`,
|
||||
} as ReflectionParameterType
|
||||
return parseParams(childObj, acc)
|
||||
},
|
||||
[]
|
||||
) || []
|
||||
)
|
||||
}
|
||||
|
||||
export function parseParams(
|
||||
current: ReflectionParameterType,
|
||||
acc: ReflectionParameterType[]
|
||||
): ReflectionParameterType[] {
|
||||
const shouldFlatten =
|
||||
current.type &&
|
||||
"declaration" in current.type &&
|
||||
current.type?.declaration?.kind === ReflectionKind.TypeLiteral &&
|
||||
current.type?.declaration?.children
|
||||
return shouldFlatten
|
||||
? [...acc, current, ...flattenParams(current)]
|
||||
: [...acc, current]
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
import { Comment, DeclarationReflection, ReflectionType } from "typedoc"
|
||||
import * as Handlebars from "handlebars"
|
||||
import { stripLineBreaks } from "../utils"
|
||||
import { ReflectionParameterType } from "../types"
|
||||
|
||||
const MAX_LEVEL = 3
|
||||
|
||||
export default function reflectionFomatter(
|
||||
reflection: ReflectionParameterType,
|
||||
level = 1
|
||||
) {
|
||||
const prefix = `${Array(level - 1)
|
||||
.fill("\t")
|
||||
.join("")}-`
|
||||
let item = `${prefix} \`${reflection.name}\`: `
|
||||
const defaultValue = getDefaultValue(reflection)
|
||||
|
||||
if (defaultValue || reflection.flags.isOptional) {
|
||||
item += `(${reflection.flags.isOptional ? "optional" : ""}${
|
||||
reflection.flags.isOptional && defaultValue ? "," : ""
|
||||
}${defaultValue ? `default: ${defaultValue}` : ""}) `
|
||||
}
|
||||
|
||||
const comments = getComments(reflection)
|
||||
|
||||
if (comments) {
|
||||
item += stripLineBreaks(Handlebars.helpers.comments(comments))
|
||||
const itemChildren: string[] = []
|
||||
comments.summary.forEach((commentSummary) => {
|
||||
if ("target" in commentSummary) {
|
||||
const reflection = commentSummary.target as DeclarationReflection
|
||||
if (reflection.children && level + 1 < MAX_LEVEL) {
|
||||
reflection.children.forEach((childItem) => {
|
||||
itemChildren.push(reflectionFomatter(childItem, level + 1))
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
if (itemChildren.length) {
|
||||
// TODO maybe we should check the type of the reflection and replace
|
||||
// `properties` with the text that makes sense for the type.
|
||||
item += ` It accepts the following properties:\n${itemChildren.join(
|
||||
"\n"
|
||||
)}`
|
||||
}
|
||||
}
|
||||
|
||||
return item
|
||||
}
|
||||
|
||||
function getDefaultValue(parameter: ReflectionParameterType): string | null {
|
||||
if (!("defaultValue" in parameter)) {
|
||||
return null
|
||||
}
|
||||
return parameter.defaultValue && parameter.defaultValue !== "..."
|
||||
? `\`${parameter.defaultValue}\``
|
||||
: null
|
||||
}
|
||||
|
||||
function getComments(parameter: ReflectionParameterType): Comment | undefined {
|
||||
if (parameter.type instanceof ReflectionType) {
|
||||
if (
|
||||
parameter.type?.declaration?.signatures &&
|
||||
parameter.type?.declaration?.signatures[0]?.comment
|
||||
) {
|
||||
return parameter.type?.declaration?.signatures[0]?.comment
|
||||
}
|
||||
}
|
||||
return parameter.comment
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"extends": "../../tsconfig",
|
||||
"compilerOptions": {
|
||||
"outDir": "./dist"
|
||||
},
|
||||
"include": ["src"]
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
dist
|
||||
.yarn
|
||||
@@ -0,0 +1,15 @@
|
||||
# typedoc-plugin-modules
|
||||
|
||||
A Typedoc plugin that includes helper plugins for documenting modules. The `resolve-reference-plugin` imitates the [`typedoc-plugin-missing-exports`](https://www.npmjs.com/package/typedoc-plugin-missing-exports) plugin.
|
||||
|
||||
## Configurations
|
||||
|
||||
Accepts the same options as the [`typedoc-plugin-missing-exports`](https://www.npmjs.com/package/typedoc-plugin-missing-exports) plugin.
|
||||
|
||||
## Build the Plugin
|
||||
|
||||
Before using any command that makes use of this plugin, make sure to run the `build` command:
|
||||
|
||||
```bash
|
||||
yarn build
|
||||
```
|
||||
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"name": "typedoc-plugin-modules",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"license": "MIT",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"description": "A plugin that holds all necessary changes to generate a module reference",
|
||||
"main": "./dist/index.js",
|
||||
"exports": "./dist/index.js",
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"author": "Shahed Nasser",
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"watch": "tsc --watch",
|
||||
"lint": "eslint --ext .ts src"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typedoc": "0.25.x"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^16.11.10",
|
||||
"typescript": "^4.6"
|
||||
},
|
||||
"keywords": [
|
||||
"typedocplugin",
|
||||
"packages",
|
||||
"monorepo",
|
||||
"typedoc"
|
||||
],
|
||||
"dependencies": {
|
||||
"glob": "^10.3.10",
|
||||
"typedoc-plugin-markdown": "^3.16.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
import { Application } from "typedoc"
|
||||
import { load as resolveReferencesPluginLoad } from "./resolve-references-plugin"
|
||||
|
||||
export function load(app: Application) {
|
||||
resolveReferencesPluginLoad(app)
|
||||
}
|
||||
@@ -0,0 +1,184 @@
|
||||
import { ok } from "assert"
|
||||
import {
|
||||
Application,
|
||||
Context,
|
||||
Converter,
|
||||
ReflectionKind,
|
||||
TypeScript as ts,
|
||||
ReferenceType,
|
||||
Reflection,
|
||||
DeclarationReflection,
|
||||
ProjectReflection,
|
||||
} from "typedoc"
|
||||
|
||||
declare module "typedoc" {
|
||||
export interface TypeDocOptionMap {
|
||||
internalModule: string
|
||||
}
|
||||
}
|
||||
|
||||
let hasMonkeyPatched = false
|
||||
|
||||
export function load(app: Application) {
|
||||
if (hasMonkeyPatched) {
|
||||
throw new Error(
|
||||
"typedoc-plugin-missing-exports cannot be loaded multiple times"
|
||||
)
|
||||
}
|
||||
hasMonkeyPatched = true
|
||||
|
||||
let activeReflection: Reflection | undefined
|
||||
const referencedSymbols = new Map<ts.Program, Set<ts.Symbol>>()
|
||||
const symbolToActiveRefl = new Map<ts.Symbol, Reflection>()
|
||||
const knownPrograms = new Map<Reflection, ts.Program>()
|
||||
|
||||
function discoverMissingExports(
|
||||
context: Context,
|
||||
program: ts.Program
|
||||
): Set<ts.Symbol> {
|
||||
// An export is missing if if was referenced
|
||||
// Is not contained in the documented
|
||||
// And is "owned" by the active reflection
|
||||
const referenced = referencedSymbols.get(program) || new Set()
|
||||
const ownedByOther = new Set<ts.Symbol>()
|
||||
referencedSymbols.set(program, ownedByOther)
|
||||
|
||||
for (const s of [...referenced]) {
|
||||
if (context.project.getReflectionFromSymbol(s)) {
|
||||
referenced.delete(s)
|
||||
} else if (symbolToActiveRefl.get(s) !== activeReflection) {
|
||||
referenced.delete(s)
|
||||
ownedByOther.add(s)
|
||||
}
|
||||
}
|
||||
|
||||
return referenced
|
||||
}
|
||||
|
||||
// Monkey patch the constructor for references so that we can get every
|
||||
const origCreateSymbolReference = ReferenceType.createSymbolReference
|
||||
ReferenceType.createSymbolReference = function (symbol, context, name) {
|
||||
ok(activeReflection, "active reflection has not been set")
|
||||
const set = referencedSymbols.get(context.program)
|
||||
symbolToActiveRefl.set(symbol, activeReflection)
|
||||
if (set) {
|
||||
set.add(symbol)
|
||||
} else {
|
||||
referencedSymbols.set(context.program, new Set([symbol]))
|
||||
}
|
||||
return origCreateSymbolReference.call(this, symbol, context, name)
|
||||
}
|
||||
|
||||
app.options.addDeclaration({
|
||||
name: "internalModule",
|
||||
help: "Define the name of the module that internal symbols which are not exported should be placed into.",
|
||||
})
|
||||
|
||||
app.converter.on(
|
||||
Converter.EVENT_CREATE_DECLARATION,
|
||||
(context: Context, refl: Reflection) => {
|
||||
if (refl.kindOf(ReflectionKind.Project | ReflectionKind.Module)) {
|
||||
knownPrograms.set(refl, context.program)
|
||||
activeReflection = refl
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
app.converter.on(
|
||||
Converter.EVENT_RESOLVE_BEGIN,
|
||||
function onResolveBegin(context: Context) {
|
||||
const modules: (DeclarationReflection | ProjectReflection)[] =
|
||||
context.project.getChildrenByKind(ReflectionKind.Module)
|
||||
if (modules.length === 0) {
|
||||
// Single entry point, just target the project.
|
||||
modules.push(context.project)
|
||||
}
|
||||
|
||||
for (const mod of modules) {
|
||||
activeReflection = mod
|
||||
|
||||
const program = knownPrograms.get(mod)
|
||||
if (!program) {
|
||||
continue
|
||||
}
|
||||
let missing = discoverMissingExports(context, program)
|
||||
if (!missing || !missing.size) {
|
||||
continue
|
||||
}
|
||||
|
||||
// Nasty hack here that will almost certainly break in future TypeDoc versions.
|
||||
context.setActiveProgram(program)
|
||||
|
||||
const internalModuleOption =
|
||||
context.converter.application.options.getValue("internalModule")
|
||||
|
||||
let internalNs: DeclarationReflection | undefined = undefined
|
||||
if (internalModuleOption) {
|
||||
internalNs = context
|
||||
.withScope(mod)
|
||||
.createDeclarationReflection(
|
||||
ReflectionKind.Module,
|
||||
void 0,
|
||||
void 0,
|
||||
context.converter.application.options.getValue("internalModule")
|
||||
)
|
||||
context.finalizeDeclarationReflection(internalNs)
|
||||
}
|
||||
|
||||
const internalContext = context.withScope(internalNs || mod)
|
||||
|
||||
// Keep track of which symbols we've tried to convert. If they don't get converted
|
||||
// when calling convertSymbol, then the user has excluded them somehow, don't go into
|
||||
// an infinite loop when converting.
|
||||
const tried = new Set<ts.Symbol>()
|
||||
|
||||
do {
|
||||
for (const s of missing) {
|
||||
if (shouldConvertSymbol(s, context.checker)) {
|
||||
internalContext.converter.convertSymbol(internalContext, s)
|
||||
}
|
||||
tried.add(s)
|
||||
}
|
||||
|
||||
missing = discoverMissingExports(context, program)
|
||||
for (const s of tried) {
|
||||
missing.delete(s)
|
||||
}
|
||||
} while (missing.size > 0)
|
||||
|
||||
// All the missing symbols were excluded, so get rid of our namespace.
|
||||
if (internalNs && !internalNs.children?.length) {
|
||||
context.project.removeReflection(internalNs)
|
||||
}
|
||||
|
||||
context.setActiveProgram(void 0)
|
||||
}
|
||||
|
||||
knownPrograms.clear()
|
||||
referencedSymbols.clear()
|
||||
symbolToActiveRefl.clear()
|
||||
},
|
||||
void 0,
|
||||
1e9
|
||||
)
|
||||
}
|
||||
function shouldConvertSymbol(symbol: ts.Symbol, checker: ts.TypeChecker) {
|
||||
while (symbol.flags & ts.SymbolFlags.Alias) {
|
||||
symbol = checker.getAliasedSymbol(symbol)
|
||||
}
|
||||
|
||||
// We're looking at an unknown symbol which is declared in some package without
|
||||
// type declarations. We know nothing about it, so don't convert it.
|
||||
if (symbol.flags & ts.SymbolFlags.Transient) {
|
||||
return false
|
||||
}
|
||||
|
||||
// This is something inside the special Node `Globals` interface. Don't convert it
|
||||
// because TypeDoc will reasonably assert that "Property" means that a symbol should be
|
||||
// inside something that can have properties.
|
||||
if (symbol.flags & ts.SymbolFlags.Property && symbol.name !== "default") {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"extends": "../../tsconfig",
|
||||
"compilerOptions": {
|
||||
"outDir": "./dist"
|
||||
},
|
||||
"include": ["src"]
|
||||
}
|
||||
+7
-3
@@ -1,13 +1,17 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es2018",
|
||||
"target": "es2021",
|
||||
"module": "commonjs",
|
||||
"outDir": "./dist",
|
||||
"isolatedModules": true,
|
||||
"esModuleInterop": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"sourceMap": true
|
||||
"sourceMap": true,
|
||||
"skipLibCheck": true,
|
||||
"rootDir": ".",
|
||||
"allowJs": true
|
||||
},
|
||||
"include": ["src"]
|
||||
"include": ["**/*.ts", "**/*.js"],
|
||||
"exclude": ["**/node_modules/**", "dist"]
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user