Added typedoc for OT Docs API Reference
This commit is contained in:
@@ -0,0 +1,246 @@
|
||||
//@ts-check
|
||||
const fs = require("fs")
|
||||
|
||||
/*////// OT DOCS GENERATOR ////////
|
||||
What does this file do?:
|
||||
Well, this file will parse the result returned from typedoc (the documentation generator).
|
||||
The resulting file will then be used in the OT Docs markdown generator to generate the Open Ticket API Reference.
|
||||
|
||||
In short:
|
||||
This file generates the documentation for Open Ticket :)
|
||||
|
||||
Contributing:
|
||||
If you want to contribute to the Open Ticket Docs, please run the following command:
|
||||
|
||||
> npm run docs
|
||||
|
||||
This will give you a "result.json" file which can then be used in the OT Docs.
|
||||
Further instructions can be found there.
|
||||
/////////////////////////////////*/
|
||||
|
||||
if (!fs.existsSync(".docs/typedoc-result.json")){
|
||||
console.log("Unable to generate documentation! Run typedoc first!")
|
||||
process.exit(1)
|
||||
}
|
||||
const result = JSON.parse(fs.readFileSync(".docs/typedoc-result.json").toString())
|
||||
const availableElements = []
|
||||
const skipElementNames = [
|
||||
"#opendiscord-types"
|
||||
]
|
||||
|
||||
const handleFunction = (memberType) => {
|
||||
if (!memberType || !memberType.signatures || !Array.isArray(memberType.signatures)) return {type:"unknown"}
|
||||
|
||||
//try to get signature
|
||||
let signature = memberType.signatures.find((s) => !s.typeParameters)
|
||||
if (!signature) signature = memberType.signatures[0]
|
||||
if (!signature) return {type:"unknown"}
|
||||
|
||||
//try to get comment
|
||||
let comment = signature.comment
|
||||
if (!comment) comment = memberType.signatures.find((s) => s.comment)?.comment
|
||||
if (!comment) comment = null
|
||||
|
||||
const signatureInherited = signature.flags.isInherited ? true : false
|
||||
const signatureComment = comment ? comment.summary?.map((c) => c.text).join("") : null
|
||||
const signatureParameters = signature.parameters?.map((p) => {
|
||||
return {name:p.name,details:handleType(p.type)}
|
||||
}) ?? []
|
||||
const signatureReturns = handleType(signature.type)
|
||||
|
||||
return {type:"function",inherited:signatureInherited,comment:signatureComment,parameters:signatureParameters,returns:signatureReturns}
|
||||
}
|
||||
|
||||
const handleType = (memberType) => {
|
||||
if (!memberType || !memberType.type) return {type:"unknown"}
|
||||
else if (memberType.type == "intrinsic") return {type:"primitive",name:memberType.name}
|
||||
else if (memberType.type == "array") return {type:"array",child:handleType(memberType.elementType)}
|
||||
else if (memberType.type == "union") return {type:"union",children:memberType.types.map((t) => handleType(t))}
|
||||
else if (memberType.type == "intersection") return {type:"intersection",children:memberType.types.map((t) => handleType(t))}
|
||||
else if (memberType.type == "reference"){
|
||||
const referenceTypeArguments = (memberType.typeArguments) ? memberType.typeArguments.map((ta) => handleType(ta)) : null
|
||||
let referenceType = availableElements.find((el) => el.name == memberType.name)?.type ?? null
|
||||
|
||||
if (referenceType){
|
||||
//member is known type (from Open Ticket)
|
||||
return {type:"reference",name:memberType.name,target:referenceType,typeArguments:referenceTypeArguments}
|
||||
}else if (memberType.package){
|
||||
//member is type from node.js or another package
|
||||
if (memberType.package == "typescript") return {type:"internal",name:memberType.name,typeArguments:referenceTypeArguments}
|
||||
if (memberType.package == "open-ticket" && memberType.refersToTypeParameter) return {type:"typeParam",name:memberType.name,typeArguments:referenceTypeArguments}
|
||||
else return {type:"external",package:memberType.package,name:memberType.name,typeArguments:referenceTypeArguments}
|
||||
}else return {type:"unknown"}
|
||||
}
|
||||
else if (memberType.type == "literal") return {type:"literal",name:(typeof memberType.value == "string") ? JSON.stringify(memberType.value) : String(memberType.value)}
|
||||
else if (memberType.type == "reflection" && memberType.declaration && memberType.declaration.signatures && memberType.declaration.signatures[0]){
|
||||
return handleFunction(memberType.declaration)
|
||||
}else if (memberType.type == "typeOperator"){
|
||||
if (memberType.operator == "keyof") return {type:"keyof",child:handleType(memberType.target)}
|
||||
else if (memberType.operator == "readonly") return {type:"readonly",child:handleType(memberType.target)}
|
||||
else if (memberType.operator == "unique") return {type:"unique",child:handleType(memberType.target)}
|
||||
}
|
||||
else if (memberType.type == "conditional") return {type:"conditional",checker:handleType(memberType.checkType),extends:handleType(memberType.extendsType),trueValue:handleType(memberType.trueType),falseValue:handleType(memberType.falseType)}
|
||||
else if (memberType.type == "indexedAccess") return {type:"index",index:handleType(memberType.indexType),object:handleType(memberType.objectType)}
|
||||
else if (memberType.type == "mapped") return {type:"mapped",parameterName:memberType.parameter,parameter:handleType(memberType.parameterType),template:handleType(memberType.templateType)}
|
||||
else if (memberType.type == "optional") return {type:"optional",child:handleType(memberType.elementType)}
|
||||
else if (memberType.type == "predicate") return {type:"predicate",name:memberType.name,target:handleType(memberType.targetType)}
|
||||
else if (memberType.type == "query") return {type:"query",target:handleType(memberType.queryType)}
|
||||
else if (memberType.type == "rest") return {type:"rest",child:handleType(memberType.elementType)}
|
||||
else if (memberType.type == "tuple") return {type:"tuple",children:memberType.elements.map((t) => handleType(t))}
|
||||
else if (memberType.type == "templateLiteral") return {type:"template",head:memberType.head,tails:memberType.tail.map((t) => {
|
||||
return {element:handleType(t[0]),text:t[1]}
|
||||
})}
|
||||
else return {type:"unknown"}
|
||||
}
|
||||
|
||||
for (const file of result.children){
|
||||
const classIds = file.groups?.find((g) => g.title == "Classes")?.children ?? []
|
||||
const interfaceIds = file.groups?.find((g) => g.title == "Interfaces")?.children ?? []
|
||||
const typeIds = file.groups?.find((g) => g.title == "Type Aliases")?.children ?? []
|
||||
const enumIds = file.groups?.find((g) => g.title == "Enumerations")?.children ?? []
|
||||
const varIds = file.groups?.find((g) => g.title == "Variables")?.children ?? []
|
||||
|
||||
for (const declaration of file.children){
|
||||
const declarationName = declaration.name
|
||||
const declarationType = classIds.includes(declaration.id) ? "class" : interfaceIds.includes(declaration.id) ? "interface" : typeIds.includes(declaration.id) ? "type" : enumIds.includes(declaration.id) ? "enum" : varIds.includes(declaration.id) ? "variable" : "other"
|
||||
availableElements.push({name:declarationName,type:declarationType})
|
||||
}
|
||||
}
|
||||
|
||||
const exported = []
|
||||
for (const file of result.children){
|
||||
const classIds = file.groups?.find((g) => g.title == "Classes")?.children ?? []
|
||||
const interfaceIds = file.groups?.find((g) => g.title == "Interfaces")?.children ?? []
|
||||
const typeIds = file.groups?.find((g) => g.title == "Type Aliases")?.children ?? []
|
||||
const enumIds = file.groups?.find((g) => g.title == "Enumerations")?.children ?? []
|
||||
const varIds = file.groups?.find((g) => g.title == "Variables")?.children ?? []
|
||||
|
||||
for (const declaration of (file.children ?? [])){
|
||||
const declarationName = declaration.name
|
||||
if (skipElementNames.includes(declarationName)) continue
|
||||
|
||||
const declarationType = classIds.includes(declaration.id) ? "class" : interfaceIds.includes(declaration.id) ? "interface" : typeIds.includes(declaration.id) ? "type" : enumIds.includes(declaration.id) ? "enum" : varIds.includes(declaration.id) ? "variable" : "other"
|
||||
const declarationTypeParams = (declaration.typeParameters) ? declaration.typeParameters.map((tp) => {
|
||||
return {name:tp.name,type:handleType(tp.type)}
|
||||
}) : null
|
||||
const declarationComment = declaration.comment?.summary?.map((c) => c.text).join("") ?? null
|
||||
const declarationConstant = declaration.flags.isConst ? true : false
|
||||
|
||||
const rawDeclarationSource = declaration.sources ? (declaration.sources[0] ?? null) : null
|
||||
const declarationSource = rawDeclarationSource ? rawDeclarationSource.fileName+":"+rawDeclarationSource.line+":"+rawDeclarationSource.character : null
|
||||
|
||||
const declarationChildren = []
|
||||
if (declarationType == "class"){
|
||||
//CLASS
|
||||
const constructorIds = declaration.groups?.find((g) => g.title == "Constructors")?.children ?? []
|
||||
const propertyIds = declaration.groups?.find((g) => g.title == "Properties")?.children ?? []
|
||||
const methodIds = declaration.groups?.find((g) => g.title == "Methods")?.children ?? []
|
||||
|
||||
for (const member of (declaration.children ?? [])){
|
||||
const memberName = member.name
|
||||
const memberType = constructorIds.includes(member.id) ? "constructor" : propertyIds.includes(member.id) ? "property" : methodIds.includes(member.id) ? "method" : "other"
|
||||
let memberComment = member.comment?.summary?.map((c) => c.text).join("") ?? null
|
||||
|
||||
const rawMemberSource = member.sources ? (member.sources[0] ?? null) : null
|
||||
let memberSource = rawMemberSource ? rawMemberSource.fileName+":"+rawMemberSource.line+":"+rawMemberSource.character : null
|
||||
|
||||
let memberDetails = null
|
||||
if (memberType == "property"){
|
||||
//CLASS => PROPERTY
|
||||
memberDetails = handleType(member.type)
|
||||
|
||||
}else if (memberType == "method"){
|
||||
//CLASS => METHOD
|
||||
memberDetails = handleFunction(member)
|
||||
memberComment = memberDetails.comment
|
||||
}
|
||||
|
||||
declarationChildren.push({
|
||||
type:memberType,
|
||||
name:memberName,
|
||||
comment:memberComment,
|
||||
source:memberSource,
|
||||
details:memberDetails
|
||||
})
|
||||
}
|
||||
}else if (declarationType == "interface"){
|
||||
//INTERFACE
|
||||
const propertyIds = declaration.groups?.find((g) => g.title == "Properties")?.children ?? []
|
||||
const methodIds = declaration.groups?.find((g) => g.title == "Methods")?.children ?? []
|
||||
|
||||
for (const member of (declaration.children ?? [])){
|
||||
const memberName = member.name
|
||||
const memberType = propertyIds.includes(member.id) ? "property" : methodIds.includes(member.id) ? "method" : "other"
|
||||
let memberComment = member.comment?.summary?.map((c) => c.text).join("") ?? null
|
||||
|
||||
const rawMemberSource = member.sources ? (member.sources[0] ?? null) : null
|
||||
let memberSource = rawMemberSource ? rawMemberSource.fileName+":"+rawMemberSource.line+":"+rawMemberSource.character : null
|
||||
|
||||
let memberDetails = null
|
||||
if (memberType == "property"){
|
||||
//INTERFACE => PROPERTY
|
||||
memberDetails = handleType(member.type)
|
||||
}else if (memberType == "method"){
|
||||
//INTERFACE => METHOD
|
||||
memberDetails = handleFunction(member)
|
||||
memberComment = memberDetails.comment
|
||||
}
|
||||
|
||||
declarationChildren.push({
|
||||
type:memberType,
|
||||
name:memberName,
|
||||
comment:memberComment,
|
||||
source:memberSource,
|
||||
details:memberDetails
|
||||
})
|
||||
}
|
||||
}else if (declarationType == "type"){
|
||||
//TYPE
|
||||
declarationChildren.push(handleType(declaration.type))
|
||||
}else if (declarationType == "enum"){
|
||||
//ENUM
|
||||
const enumerableIds = declaration.groups?.find((g) => g.title == "Enumeration Members")?.children ?? []
|
||||
|
||||
for (const member of (declaration.children ?? [])){
|
||||
const memberName = member.name
|
||||
const memberType = enumerableIds.includes(member.id) ? "enumerable" : "other"
|
||||
const memberComment = member.comment?.summary?.map((c) => c.text).join("") ?? null
|
||||
|
||||
const rawMemberSource = member.sources ? (member.sources[0] ?? null) : null
|
||||
let memberSource = rawMemberSource ? rawMemberSource.fileName+":"+rawMemberSource.line+":"+rawMemberSource.character : null
|
||||
|
||||
let memberDetails = null
|
||||
if (memberType == "enumerable"){
|
||||
//INTERFACE => PROPERTY
|
||||
memberDetails = handleType(member.type)
|
||||
}
|
||||
|
||||
declarationChildren.push({
|
||||
type:memberType,
|
||||
name:memberName,
|
||||
comment:memberComment,
|
||||
source:memberSource,
|
||||
details:memberDetails
|
||||
})
|
||||
}
|
||||
}else if (declarationType == "variable"){
|
||||
//VARIABLE
|
||||
declarationChildren.push(handleType(declaration.type))
|
||||
|
||||
}else if (declarationType == "other"){
|
||||
}
|
||||
|
||||
exported.push({
|
||||
type:declarationType,
|
||||
name:declarationName,
|
||||
comment:declarationComment,
|
||||
constant:declarationConstant,
|
||||
source:declarationSource,
|
||||
children:declarationChildren,
|
||||
typeParams:declarationTypeParams
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fs.writeFileSync(".docs/result.json",JSON.stringify(exported,null,"\t"))
|
||||
fs.rmSync(".docs/typedoc-result.json")
|
||||
Reference in New Issue
Block a user