Added custom typedoc theme
This commit is contained in:
parent
a6a74726aa
commit
ad310f6e84
6 changed files with 403 additions and 2 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -2,3 +2,4 @@ node_modules
|
||||||
.vitepress/dist
|
.vitepress/dist
|
||||||
docs/api
|
docs/api
|
||||||
components
|
components
|
||||||
|
typedoc-theme
|
||||||
|
|
|
@ -7,8 +7,7 @@
|
||||||
"serve": "vitepress serve docs",
|
"serve": "vitepress serve docs",
|
||||||
"dev": "vitepress dev docs",
|
"dev": "vitepress dev docs",
|
||||||
"build": "vitepress build docs",
|
"build": "vitepress build docs",
|
||||||
"typedoc": "cd profectus && vue-typedoc --logLevel Verbose --plugin typedoc-plugin-markdown --hideBreadcrumbs --hideInPageTOC --entryDocument index.md --plugin typedoc-plugin-rename-defaults --plugin typedoc-plugin-mdn-links",
|
"generate": "tsc --project ./profectus-theme && cd profectus && vue-typedoc --logLevel Verbose --plugin ../typedoc-theme/index.js --theme profectus --plugin typedoc-plugin-markdown --plugin typedoc-plugin-rename-defaults --plugin typedoc-plugin-mdn-links && cd .. && vue-docgen -c docgen.config.js && node copyComponents.js"
|
||||||
"docgen": "vue-docgen -c docgen.config.js && node copyComponents.js"
|
|
||||||
},
|
},
|
||||||
"repository": "git+https://github.com/profectus-engine/profectus-docs.git",
|
"repository": "git+https://github.com/profectus-engine/profectus-docs.git",
|
||||||
"author": "thepaperpilot",
|
"author": "thepaperpilot",
|
||||||
|
|
7
profectus-theme/index.ts
Normal file
7
profectus-theme/index.ts
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
import { Application } from 'typedoc';
|
||||||
|
|
||||||
|
import { ProfectusTheme } from './theme';
|
||||||
|
|
||||||
|
export function load(app: Application) {
|
||||||
|
app.renderer.defineTheme('profectus', ProfectusTheme);
|
||||||
|
}
|
47
profectus-theme/theme.ts
Normal file
47
profectus-theme/theme.ts
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
import * as fs from 'fs';
|
||||||
|
|
||||||
|
import {
|
||||||
|
ContainerReflection,
|
||||||
|
PageEvent,
|
||||||
|
Renderer,
|
||||||
|
DeclarationReflection,
|
||||||
|
RendererEvent
|
||||||
|
} from 'typedoc';
|
||||||
|
import { MarkdownTheme } from 'typedoc-plugin-markdown';
|
||||||
|
import registerTypeHelper from './type';
|
||||||
|
|
||||||
|
export class ProfectusTheme extends MarkdownTheme {
|
||||||
|
constructor(renderer: Renderer) {
|
||||||
|
super(renderer);
|
||||||
|
|
||||||
|
console.log("!?!?!")
|
||||||
|
this.entryDocument = 'index.md';
|
||||||
|
this.hideBreadcrumbs = true;
|
||||||
|
this.hideInPageTOC = true;
|
||||||
|
|
||||||
|
registerTypeHelper();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
getReflectionTemplate() {
|
||||||
|
const templ = super.getReflectionTemplate();
|
||||||
|
return (pageEvent) => {
|
||||||
|
if (pageEvent.url === "index.md") {
|
||||||
|
return "# Profectus API";
|
||||||
|
}
|
||||||
|
return templ(pageEvent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getRelativeUrl(url: string) {
|
||||||
|
const relativeUrl = super
|
||||||
|
.getRelativeUrl(url)
|
||||||
|
.replace(/(.*).md/, '$1')
|
||||||
|
.replace(/ /g, '-');
|
||||||
|
return relativeUrl.startsWith('..') ? relativeUrl : './' + relativeUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
toUrl(mapping: any, reflection: DeclarationReflection) {
|
||||||
|
return `${mapping.directory}/${reflection.getFullName()}.md`;
|
||||||
|
}
|
||||||
|
}
|
18
profectus-theme/tsconfig.json
Normal file
18
profectus-theme/tsconfig.json
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "../typedoc-theme",
|
||||||
|
"noErrorTruncation": true,
|
||||||
|
"target": "esnext",
|
||||||
|
"module": "commonjs",
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"experimentalDecorators": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"sourceMap": true,
|
||||||
|
"lib": [
|
||||||
|
"esnext",
|
||||||
|
"dom",
|
||||||
|
"dom.iterable",
|
||||||
|
"scripthost"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
329
profectus-theme/type.ts
Normal file
329
profectus-theme/type.ts
Normal file
|
@ -0,0 +1,329 @@
|
||||||
|
import * as Handlebars from 'handlebars';
|
||||||
|
import {
|
||||||
|
ArrayType,
|
||||||
|
ConditionalType,
|
||||||
|
DeclarationReflection,
|
||||||
|
IndexedAccessType,
|
||||||
|
InferredType,
|
||||||
|
IntersectionType,
|
||||||
|
IntrinsicType,
|
||||||
|
LiteralType,
|
||||||
|
MappedType,
|
||||||
|
PredicateType,
|
||||||
|
QueryType,
|
||||||
|
ReferenceType,
|
||||||
|
ReflectionType,
|
||||||
|
SignatureReflection,
|
||||||
|
TupleType,
|
||||||
|
TypeOperatorType,
|
||||||
|
UnionType,
|
||||||
|
UnknownType,
|
||||||
|
} from 'typedoc';
|
||||||
|
|
||||||
|
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
|
||||||
|
| LiteralType
|
||||||
|
| MappedType,
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this instanceof MappedType) {
|
||||||
|
return getMappedType(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this instanceof PredicateType) {
|
||||||
|
return getPredicateType(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this ? escapeChars(this.toString()) : '';
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPredicateType(model: PredicateType) {
|
||||||
|
return `${model.asserts ? "asserts " : ""}\`${model.name}\` is ${Handlebars.helpers.type.call(model.targetType)}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getMappedType(model: MappedType) {
|
||||||
|
return `\{ ${model.readonlyModifier === "+" ? "readonly" : model.readonlyModifier === "-" ? "-readonly" : ""}[\`${model.parameter}\` in ${Handlebars.helpers.type.call(model.parameterType)}]${model.optionalModifier === "+" ? "?" : model.optionalModifier === "-" ? "-?" : ""}: ${Handlebars.helpers.type.call(model.templateType)} \}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getLiteralType(model: LiteralType) {
|
||||||
|
if (typeof model.value === 'bigint') {
|
||||||
|
return `\`${model.value}n\``;
|
||||||
|
}
|
||||||
|
return `\`\`${JSON.stringify(model.value)}\`\``;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getReflectionType(
|
||||||
|
model: DeclarationReflection | ReflectionType,
|
||||||
|
collapse: Collapse,
|
||||||
|
) {
|
||||||
|
const root = model instanceof ReflectionType ? model.declaration : model;
|
||||||
|
if (root.signatures) {
|
||||||
|
return collapse === 'function' || collapse === 'all'
|
||||||
|
? `\`fn\``
|
||||||
|
: getFunctionType(root.signatures);
|
||||||
|
}
|
||||||
|
return collapse === 'object' || collapse === 'all'
|
||||||
|
? `\`Object\``
|
||||||
|
: getDeclarationType(root);
|
||||||
|
}
|
||||||
|
|
||||||
|
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('');
|
||||||
|
}
|
||||||
|
|
||||||
|
function getReferenceType(model: ReferenceType, emphasis) {
|
||||||
|
const externalUrl = Handlebars.helpers.attemptExternalResolution(model);
|
||||||
|
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(
|
||||||
|
externalUrl
|
||||||
|
? `[${`\`${model.name}\``}]( ${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
|
||||||
|
? externalUrl
|
||||||
|
? `[${`\`${model.name}\``}]( ${externalUrl} )`
|
||||||
|
: `\`${model.name}\``
|
||||||
|
: escapeChars(model.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getArrayType(model: ArrayType, emphasis: boolean) {
|
||||||
|
const arrayType = Handlebars.helpers.type.call(
|
||||||
|
model.elementType,
|
||||||
|
'none',
|
||||||
|
emphasis,
|
||||||
|
);
|
||||||
|
return model.elementType.type === 'union'
|
||||||
|
? `(${arrayType})[]`
|
||||||
|
: `${arrayType}[]`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getUnionType(model: UnionType, emphasis: boolean) {
|
||||||
|
return model.types
|
||||||
|
.map((unionType) =>
|
||||||
|
Handlebars.helpers.type.call(unionType, 'none', emphasis),
|
||||||
|
)
|
||||||
|
.join(` \\| `);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getIntersectionType(model: IntersectionType) {
|
||||||
|
return model.types
|
||||||
|
.map((intersectionType) => Handlebars.helpers.type.call(intersectionType))
|
||||||
|
.join(' & ');
|
||||||
|
}
|
||||||
|
|
||||||
|
function getTupleType(model: TupleType) {
|
||||||
|
return `[${model.elements
|
||||||
|
.map((element) => Handlebars.helpers.type.call(element))
|
||||||
|
.join(', ')}]`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getIntrinsicType(model: IntrinsicType, emphasis: boolean) {
|
||||||
|
return emphasis ? `\`${model.name}\`` : escapeChars(model.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getTypeOperatorType(model: TypeOperatorType) {
|
||||||
|
return `${model.operator} ${Handlebars.helpers.type.call(model.target)}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getQueryType(model: QueryType) {
|
||||||
|
return `typeof ${Handlebars.helpers.type.call(model.queryType)}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getInferredType(model: InferredType) {
|
||||||
|
return `infer ${escapeChars(model.name)}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getUnknownType(model: UnknownType) {
|
||||||
|
return escapeChars(model.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
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(' ');
|
||||||
|
}
|
||||||
|
|
||||||
|
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('');
|
||||||
|
}
|
||||||
|
|
||||||
|
function escapeChars(str: string) {
|
||||||
|
return str
|
||||||
|
.replace(/>/g, '\\>')
|
||||||
|
.replace(/_/g, '\\_')
|
||||||
|
.replace(/`/g, '\\`')
|
||||||
|
.replace(/\|/g, '\\|');
|
||||||
|
}
|
Loading…
Reference in a new issue