2024-06-13 13:09:27 +00:00
|
|
|
import { APIGroup } from '@/types/content-types'
|
|
|
|
import { TldrawApiModel } from '@/utils/TldrawApiModel'
|
2024-01-15 12:33:15 +00:00
|
|
|
import {
|
|
|
|
ApiClass,
|
|
|
|
ApiConstructSignature,
|
|
|
|
ApiConstructor,
|
|
|
|
ApiDeclaredItem,
|
|
|
|
ApiDocumentedItem,
|
|
|
|
ApiEnum,
|
|
|
|
ApiFunction,
|
|
|
|
ApiInterface,
|
|
|
|
ApiItem,
|
|
|
|
ApiItemKind,
|
|
|
|
ApiMethod,
|
|
|
|
ApiMethodSignature,
|
|
|
|
ApiNamespace,
|
|
|
|
ApiProperty,
|
|
|
|
ApiPropertySignature,
|
|
|
|
ApiReadonlyMixin,
|
|
|
|
ApiReleaseTagMixin,
|
|
|
|
ApiStaticMixin,
|
|
|
|
ApiTypeAlias,
|
|
|
|
ApiVariable,
|
|
|
|
Excerpt,
|
|
|
|
ReleaseTag,
|
|
|
|
} from '@microsoft/api-extractor-model'
|
|
|
|
import { MarkdownWriter, formatWithPrettier, getPath, getSlug } from '../utils'
|
|
|
|
|
2024-05-22 15:55:49 +00:00
|
|
|
interface Result {
|
|
|
|
markdown: string
|
|
|
|
keywords: string[]
|
|
|
|
}
|
2024-01-15 12:33:15 +00:00
|
|
|
|
|
|
|
const REPO_URL = 'https://github.com/tldraw/tldraw/blob/main/'
|
|
|
|
|
|
|
|
const date = new Intl.DateTimeFormat('en-US', {
|
|
|
|
year: 'numeric',
|
|
|
|
month: '2-digit',
|
|
|
|
day: '2-digit',
|
|
|
|
}).format(new Date())
|
|
|
|
|
2024-06-13 13:09:27 +00:00
|
|
|
export async function getApiMarkdown(
|
|
|
|
model: TldrawApiModel,
|
|
|
|
categoryName: string,
|
|
|
|
item: ApiItem,
|
|
|
|
j: number
|
|
|
|
) {
|
2024-01-15 12:33:15 +00:00
|
|
|
const result: Result = { markdown: '', keywords: [] }
|
|
|
|
const toc: Result = { markdown: '', keywords: [] }
|
|
|
|
const membersResult: Result = { markdown: '', keywords: [] }
|
|
|
|
|
2024-06-13 13:09:27 +00:00
|
|
|
const isComponent = model.isComponent(item)
|
|
|
|
const componentProps = isComponent ? model.getReactPropsItem(item) : null
|
|
|
|
|
|
|
|
const members = componentProps?.members ?? item.members
|
|
|
|
if (members) {
|
2024-01-15 12:33:15 +00:00
|
|
|
const constructors = []
|
|
|
|
const properties = []
|
|
|
|
const methods = []
|
2024-06-13 13:09:27 +00:00
|
|
|
for (const member of members) {
|
2024-01-15 12:33:15 +00:00
|
|
|
switch (member.kind) {
|
|
|
|
case ApiItemKind.Constructor:
|
|
|
|
case ApiItemKind.ConstructSignature:
|
|
|
|
constructors.push(member)
|
|
|
|
break
|
|
|
|
case ApiItemKind.Variable:
|
|
|
|
case ApiItemKind.Property:
|
|
|
|
case ApiItemKind.PropertySignature:
|
|
|
|
properties.push(member)
|
|
|
|
break
|
|
|
|
case ApiItemKind.Method:
|
|
|
|
case ApiItemKind.Function:
|
|
|
|
case ApiItemKind.MethodSignature:
|
2024-06-13 13:09:27 +00:00
|
|
|
if (isComponent) {
|
|
|
|
properties.push(member)
|
|
|
|
} else {
|
|
|
|
methods.push(member)
|
|
|
|
}
|
2024-01-15 12:33:15 +00:00
|
|
|
|
|
|
|
break
|
|
|
|
case ApiItemKind.EnumMember:
|
|
|
|
case ApiItemKind.Class:
|
|
|
|
case ApiItemKind.TypeAlias:
|
|
|
|
case ApiItemKind.Interface:
|
|
|
|
// TODO: document these
|
|
|
|
break
|
|
|
|
default:
|
|
|
|
throw new Error(`Unknown member kind: ${member.kind} ${member.displayName}`)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const constructorResult: Result = { markdown: '', keywords: [] }
|
|
|
|
const propertiesResult: Result = { markdown: '', keywords: [] }
|
|
|
|
const methodsResult: Result = { markdown: '', keywords: [] }
|
|
|
|
|
|
|
|
if (constructors.length) {
|
|
|
|
for (const member of constructors) {
|
2024-06-13 13:09:27 +00:00
|
|
|
await addMarkdownForMember(model, constructorResult, member)
|
2024-01-15 12:33:15 +00:00
|
|
|
addHorizontalRule(constructorResult)
|
|
|
|
}
|
|
|
|
addMarkdown(membersResult, constructorResult.markdown)
|
|
|
|
}
|
|
|
|
|
2024-06-13 13:09:27 +00:00
|
|
|
if (properties.length || componentProps) {
|
2024-01-15 12:33:15 +00:00
|
|
|
addMarkdown(propertiesResult, `## Properties\n\n`)
|
2024-06-13 13:09:27 +00:00
|
|
|
if (componentProps) addExtends(propertiesResult, componentProps)
|
2024-01-15 12:33:15 +00:00
|
|
|
for (const member of properties) {
|
|
|
|
const slug = getSlug(member)
|
|
|
|
addMarkdown(toc, ` - [${member.displayName}](#${slug})\n`)
|
2024-06-13 13:09:27 +00:00
|
|
|
await addMarkdownForMember(model, propertiesResult, member, {
|
|
|
|
isComponentProp: isComponent,
|
|
|
|
})
|
2024-01-15 12:33:15 +00:00
|
|
|
addHorizontalRule(propertiesResult)
|
|
|
|
}
|
2024-06-13 13:09:27 +00:00
|
|
|
if (
|
|
|
|
componentProps &&
|
|
|
|
componentProps instanceof ApiDeclaredItem &&
|
|
|
|
componentProps?.kind !== 'Interface'
|
|
|
|
) {
|
2024-06-13 13:47:13 +00:00
|
|
|
propertiesResult.markdown += await excerptToMarkdown(
|
|
|
|
componentProps,
|
|
|
|
componentProps.excerpt,
|
|
|
|
{
|
|
|
|
kind: componentProps.kind,
|
|
|
|
}
|
|
|
|
)
|
2024-06-13 13:09:27 +00:00
|
|
|
}
|
|
|
|
if (propertiesResult.markdown.trim()) {
|
|
|
|
addMarkdown(toc, `- [Properties](#properties)\n`)
|
|
|
|
addMarkdown(membersResult, propertiesResult.markdown)
|
|
|
|
}
|
2024-01-15 12:33:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (methods.length) {
|
|
|
|
addMarkdown(toc, `- [Methods](#methods)\n`)
|
|
|
|
addMarkdown(methodsResult, `## Methods\n\n`)
|
|
|
|
for (const member of methods) {
|
|
|
|
const slug = getSlug(member)
|
|
|
|
addMarkdown(toc, ` - [${member.displayName}](#${slug})\n`)
|
2024-06-13 13:09:27 +00:00
|
|
|
await addMarkdownForMember(model, methodsResult, member)
|
2024-01-15 12:33:15 +00:00
|
|
|
addHorizontalRule(methodsResult)
|
|
|
|
}
|
|
|
|
addMarkdown(membersResult, methodsResult.markdown)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-06-13 13:09:27 +00:00
|
|
|
await addFrontmatter(model, result, item, categoryName, j)
|
2024-01-15 12:33:15 +00:00
|
|
|
|
|
|
|
if (toc.markdown.length) {
|
2024-02-01 14:16:17 +00:00
|
|
|
result.markdown += `<details className="article__table-of-contents">\n\t<summary>Table of contents</summary>\n`
|
2024-01-15 12:33:15 +00:00
|
|
|
addMarkdown(result, toc.markdown)
|
|
|
|
result.markdown += `</details>\n\n`
|
|
|
|
}
|
|
|
|
|
2024-06-13 13:09:27 +00:00
|
|
|
addTags(model, result, item)
|
2024-01-15 12:33:15 +00:00
|
|
|
|
2024-06-13 13:09:27 +00:00
|
|
|
await addDocComment(model, result, item)
|
2024-01-15 12:33:15 +00:00
|
|
|
|
|
|
|
addLinkToSource(result, item)
|
|
|
|
|
|
|
|
if (membersResult.markdown.length) {
|
|
|
|
addHorizontalRule(result)
|
|
|
|
addMarkdown(result, membersResult.markdown)
|
|
|
|
}
|
|
|
|
|
|
|
|
return result
|
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------- Helpers -------------------- */
|
|
|
|
|
|
|
|
function addMarkdown(result: Result, markdown: string) {
|
|
|
|
result.markdown += markdown
|
|
|
|
}
|
|
|
|
|
2024-06-13 13:09:27 +00:00
|
|
|
async function addMarkdownForMember(
|
|
|
|
model: TldrawApiModel,
|
|
|
|
result: Result,
|
|
|
|
member: ApiItem,
|
|
|
|
{ isComponentProp = false } = {}
|
|
|
|
) {
|
2024-01-15 12:33:15 +00:00
|
|
|
if (member.displayName.startsWith('_')) return
|
|
|
|
addMemberName(result, member)
|
2024-06-13 13:09:27 +00:00
|
|
|
addTags(model, result, member, { isComponentProp })
|
|
|
|
await addDocComment(model, result, member, { isComponentProp })
|
2024-01-15 12:33:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
async function addFrontmatter(
|
2024-06-13 13:09:27 +00:00
|
|
|
model: TldrawApiModel,
|
2024-01-15 12:33:15 +00:00
|
|
|
result: Result,
|
|
|
|
member: ApiItem,
|
|
|
|
categoryName: string,
|
|
|
|
order: number
|
|
|
|
) {
|
|
|
|
let description = ''
|
|
|
|
if (member instanceof ApiDocumentedItem && member.tsdocComment) {
|
|
|
|
const comment = await MarkdownWriter.docNodeToMarkdown(
|
|
|
|
member,
|
|
|
|
member.tsdocComment.summarySection
|
|
|
|
)
|
|
|
|
// only up to the first newline
|
|
|
|
description = comment.trim().split('\n')[0].replace(/:/g, '')
|
|
|
|
}
|
|
|
|
|
|
|
|
let kw = ''
|
|
|
|
|
|
|
|
if (result.keywords.length) {
|
|
|
|
kw += `\nkeywords:`
|
|
|
|
for (const k of result.keywords) {
|
|
|
|
if (k.startsWith('_')) continue
|
|
|
|
kw += `\n - ${k.trim().split('\n')[0]}`
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
result.markdown += `---
|
|
|
|
title: ${member.displayName}
|
|
|
|
status: published
|
|
|
|
description: ${description}
|
|
|
|
category: ${categoryName}
|
2024-06-13 13:09:27 +00:00
|
|
|
group: ${model.isComponent(member) ? APIGroup.Component : member.kind}
|
2024-01-15 12:33:15 +00:00
|
|
|
author: api
|
|
|
|
date: ${date}
|
|
|
|
order: ${order}
|
|
|
|
sourceUrl: ${'_fileUrlPath' in member ? member._fileUrlPath : ''}${kw}
|
|
|
|
---
|
|
|
|
`
|
|
|
|
}
|
|
|
|
|
|
|
|
function addHorizontalRule(result: Result) {
|
|
|
|
result.markdown += `---\n\n`
|
|
|
|
}
|
|
|
|
|
|
|
|
function addMemberName(result: Result, member: ApiItem) {
|
|
|
|
if (member.kind === 'Constructor') {
|
|
|
|
result.markdown += `### Constructor\n\n`
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!member.displayName) return
|
|
|
|
result.markdown += `### \`${member.displayName}${member.kind === 'Method' ? '()' : ''}\`\n\n`
|
|
|
|
}
|
|
|
|
|
2024-06-13 13:09:27 +00:00
|
|
|
async function addDocComment(
|
|
|
|
model: TldrawApiModel,
|
|
|
|
result: Result,
|
|
|
|
member: ApiItem,
|
|
|
|
{ isComponentProp = false } = {}
|
|
|
|
) {
|
2024-01-15 12:33:15 +00:00
|
|
|
if (!(member instanceof ApiDocumentedItem)) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2024-06-13 13:09:27 +00:00
|
|
|
const isComponent = model.isComponent(member)
|
|
|
|
|
2024-01-15 12:33:15 +00:00
|
|
|
if (member.tsdocComment) {
|
|
|
|
result.markdown += await MarkdownWriter.docNodeToMarkdown(
|
|
|
|
member,
|
|
|
|
member.tsdocComment.summarySection
|
|
|
|
)
|
|
|
|
|
|
|
|
const exampleBlocks = member.tsdocComment.customBlocks.filter(
|
|
|
|
(block) => block.blockTag.tagNameWithUpperCase === '@EXAMPLE'
|
|
|
|
)
|
|
|
|
|
|
|
|
if (exampleBlocks.length) {
|
|
|
|
result.markdown += `\n\n`
|
2024-02-29 16:28:45 +00:00
|
|
|
result.markdown += `<ApiHeading>Example</ApiHeading>\n\n`
|
2024-01-15 12:33:15 +00:00
|
|
|
for (const example of exampleBlocks) {
|
|
|
|
result.markdown += await MarkdownWriter.docNodeToMarkdown(member, example.content)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (
|
|
|
|
member instanceof ApiVariable ||
|
|
|
|
member instanceof ApiTypeAlias ||
|
|
|
|
member instanceof ApiProperty ||
|
|
|
|
member instanceof ApiPropertySignature ||
|
|
|
|
member instanceof ApiClass ||
|
|
|
|
member instanceof ApiFunction ||
|
|
|
|
member instanceof ApiInterface ||
|
|
|
|
member instanceof ApiEnum ||
|
|
|
|
member instanceof ApiNamespace ||
|
|
|
|
member instanceof ApiMethod
|
|
|
|
) {
|
2024-06-13 13:09:27 +00:00
|
|
|
if (!isComponentProp) result.markdown += `<ApiHeading>Signature</ApiHeading>\n\n`
|
2024-06-13 13:47:13 +00:00
|
|
|
result.markdown += await excerptToMarkdown(member, member.excerpt, {
|
2024-01-15 12:33:15 +00:00
|
|
|
kind: member.kind,
|
|
|
|
})
|
|
|
|
result.markdown += `\n\n`
|
|
|
|
}
|
|
|
|
|
2024-06-13 13:09:27 +00:00
|
|
|
if (isComponent) return
|
|
|
|
|
2024-01-15 12:33:15 +00:00
|
|
|
if (
|
|
|
|
member instanceof ApiMethod ||
|
|
|
|
member instanceof ApiMethodSignature ||
|
|
|
|
member instanceof ApiConstructor ||
|
|
|
|
member instanceof ApiConstructSignature ||
|
|
|
|
member instanceof ApiFunction
|
|
|
|
) {
|
|
|
|
if (!member.parameters.length) {
|
|
|
|
return
|
|
|
|
} else {
|
|
|
|
result.markdown += `<ApiHeading>Parameters</ApiHeading>\n\n`
|
|
|
|
result.markdown += '<ParametersTable>\n\n'
|
|
|
|
for (const param of member.parameters) {
|
|
|
|
result.markdown += '<ParametersTableRow>\n'
|
|
|
|
result.markdown += '<ParametersTableName>\n\n'
|
|
|
|
result.markdown += `\`${param.name}\`\n\n`
|
|
|
|
result.markdown += `</ParametersTableName>\n`
|
|
|
|
result.markdown += `<ParametersTableDescription>\n\n`
|
2024-06-13 13:47:13 +00:00
|
|
|
result.markdown += await excerptToMarkdown(member, param.parameterTypeExcerpt, {
|
2024-01-15 12:33:15 +00:00
|
|
|
kind: 'ParameterType',
|
|
|
|
printWidth: 60,
|
|
|
|
})
|
|
|
|
result.markdown += `\n\n`
|
|
|
|
if (param.tsdocParamBlock) {
|
|
|
|
result.markdown += await MarkdownWriter.docNodeToMarkdown(
|
|
|
|
member,
|
|
|
|
param.tsdocParamBlock.content
|
|
|
|
)
|
|
|
|
}
|
|
|
|
result.markdown += `\n\n</ParametersTableDescription>\n`
|
|
|
|
result.markdown += `</ParametersTableRow>\n`
|
|
|
|
}
|
|
|
|
result.markdown += '</ParametersTable>\n\n'
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!(member instanceof ApiConstructor)) {
|
|
|
|
result.markdown += `<ApiHeading>Returns</ApiHeading>\n\n`
|
2024-06-13 13:47:13 +00:00
|
|
|
result.markdown += await excerptToMarkdown(member, member.returnTypeExcerpt, {
|
2024-01-15 12:33:15 +00:00
|
|
|
kind: 'ReturnType',
|
|
|
|
})
|
|
|
|
result.markdown += `\n\n`
|
|
|
|
if (member.tsdocComment && member.tsdocComment.returnsBlock) {
|
|
|
|
result.markdown += await MarkdownWriter.docNodeToMarkdown(
|
|
|
|
member,
|
|
|
|
member.tsdocComment.returnsBlock.content
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if (
|
|
|
|
member instanceof ApiVariable ||
|
|
|
|
member instanceof ApiTypeAlias ||
|
|
|
|
member instanceof ApiProperty ||
|
|
|
|
member instanceof ApiPropertySignature ||
|
|
|
|
member instanceof ApiClass ||
|
|
|
|
member instanceof ApiInterface ||
|
|
|
|
member instanceof ApiEnum ||
|
|
|
|
member instanceof ApiNamespace
|
|
|
|
) {
|
|
|
|
const params = member.tsdocComment?.params
|
|
|
|
if (params && params.count > 0) {
|
|
|
|
result.markdown += `<ApiHeading>Parameters</ApiHeading>\n\n`
|
|
|
|
result.markdown += '<ParametersTable>\n\n'
|
|
|
|
for (const block of params.blocks) {
|
|
|
|
result.markdown += '<ParametersTableRow>\n'
|
|
|
|
result.markdown += '<ParametersTableName>\n\n'
|
|
|
|
result.markdown += `\`${block.parameterName}\`\n\n`
|
|
|
|
result.markdown += `</ParametersTableName>\n`
|
|
|
|
result.markdown += `<ParametersTableDescription>\n\n`
|
|
|
|
result.markdown += await MarkdownWriter.docNodeToMarkdown(member, block.content)
|
|
|
|
result.markdown += `\n\n</ParametersTableDescription>\n`
|
|
|
|
result.markdown += `</ParametersTableRow>\n`
|
|
|
|
}
|
|
|
|
result.markdown += '</ParametersTable>\n\n'
|
|
|
|
}
|
|
|
|
} else {
|
2024-06-13 13:09:27 +00:00
|
|
|
model.error(member, `Unknown member kind: ${member.kind}`)
|
2024-01-15 12:33:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-06-13 13:47:13 +00:00
|
|
|
async function excerptToMarkdown(
|
|
|
|
item: ApiItem,
|
2024-01-15 12:33:15 +00:00
|
|
|
excerpt: Excerpt,
|
|
|
|
{ kind, printWidth }: { kind: ApiItemKind | 'ReturnType' | 'ParameterType'; printWidth?: number }
|
|
|
|
) {
|
2024-06-13 13:47:13 +00:00
|
|
|
const links = {} as Record<string, string>
|
|
|
|
|
2024-01-15 12:33:15 +00:00
|
|
|
let code = ''
|
|
|
|
for (const token of excerpt.spannedTokens) {
|
|
|
|
code += token.text
|
2024-06-13 13:47:13 +00:00
|
|
|
|
|
|
|
if (!token.canonicalReference) continue
|
|
|
|
|
|
|
|
const apiItemResult = item
|
|
|
|
.getAssociatedModel()!
|
|
|
|
.resolveDeclarationReference(token.canonicalReference!, item)
|
|
|
|
|
|
|
|
if (apiItemResult.errorMessage) continue
|
|
|
|
|
|
|
|
const apiItem = apiItemResult.resolvedApiItem!
|
|
|
|
const url = `/reference/${getPath(apiItem)}`
|
|
|
|
links[token.text] = url
|
2024-01-15 12:33:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
code = code.replace(/^export /, '')
|
|
|
|
code = code.replace(/^declare /, '')
|
|
|
|
|
|
|
|
switch (kind) {
|
|
|
|
case ApiItemKind.CallSignature:
|
|
|
|
case ApiItemKind.EntryPoint:
|
|
|
|
case ApiItemKind.EnumMember:
|
|
|
|
case ApiItemKind.Function:
|
|
|
|
case ApiItemKind.Model:
|
|
|
|
case ApiItemKind.Namespace:
|
|
|
|
case ApiItemKind.None:
|
|
|
|
case ApiItemKind.Package:
|
|
|
|
case ApiItemKind.TypeAlias:
|
|
|
|
code = await formatWithPrettier(code, { printWidth })
|
|
|
|
break
|
|
|
|
case 'ReturnType':
|
|
|
|
case 'ParameterType':
|
|
|
|
code = await formatWithPrettier(`type X = () =>${code}`, { printWidth })
|
|
|
|
if (!code.startsWith('type X = () =>')) {
|
|
|
|
throw Error()
|
|
|
|
}
|
|
|
|
code = code = code.replace(/^type X = \(\) =>[ \n]/, '')
|
|
|
|
break
|
|
|
|
case ApiItemKind.Class:
|
|
|
|
case ApiItemKind.Enum:
|
|
|
|
case ApiItemKind.Interface:
|
|
|
|
code = await formatWithPrettier(`${code} {}`, { printWidth })
|
|
|
|
break
|
|
|
|
case ApiItemKind.Constructor:
|
|
|
|
case ApiItemKind.ConstructSignature:
|
|
|
|
case ApiItemKind.IndexSignature:
|
|
|
|
case ApiItemKind.Method:
|
|
|
|
case ApiItemKind.MethodSignature:
|
|
|
|
case ApiItemKind.Property:
|
|
|
|
case ApiItemKind.PropertySignature:
|
|
|
|
case ApiItemKind.Variable:
|
|
|
|
code = await formatWithPrettier(`class X { ${code} }`, { printWidth })
|
|
|
|
if (!(code.startsWith('class X {\n') && code.endsWith('\n}'))) {
|
|
|
|
throw Error()
|
|
|
|
}
|
|
|
|
code = code.slice('class X {\n'.length, -'\n}'.length)
|
|
|
|
code = code.replace(/^ {2}/gm, '')
|
|
|
|
break
|
|
|
|
default:
|
|
|
|
throw Error()
|
|
|
|
}
|
|
|
|
|
2024-06-13 13:47:13 +00:00
|
|
|
return [
|
|
|
|
`<CodeLinkProvider links={${JSON.stringify(links)}}>`,
|
|
|
|
'',
|
|
|
|
'```ts',
|
|
|
|
code,
|
|
|
|
'```',
|
|
|
|
'',
|
|
|
|
'</CodeLinkProvider>',
|
|
|
|
].join('\n')
|
2024-01-15 12:33:15 +00:00
|
|
|
}
|
|
|
|
|
2024-06-13 13:09:27 +00:00
|
|
|
function addTags(
|
|
|
|
model: TldrawApiModel,
|
|
|
|
result: Result,
|
|
|
|
member: ApiItem,
|
|
|
|
{ isComponentProp = false } = {}
|
|
|
|
) {
|
2024-01-15 12:33:15 +00:00
|
|
|
const tags = []
|
2024-06-13 13:09:27 +00:00
|
|
|
if (!isComponentProp) {
|
|
|
|
if (ApiReleaseTagMixin.isBaseClassOf(member)) {
|
|
|
|
tags.push(ReleaseTag[member.releaseTag])
|
|
|
|
}
|
|
|
|
if (ApiStaticMixin.isBaseClassOf(member) && member.isStatic) {
|
|
|
|
tags.push('static')
|
|
|
|
}
|
|
|
|
if (ApiReadonlyMixin.isBaseClassOf(member) && member.isReadonly) {
|
|
|
|
tags.push('readonly')
|
|
|
|
}
|
2024-01-15 12:33:15 +00:00
|
|
|
}
|
2024-06-13 13:09:27 +00:00
|
|
|
if (member instanceof ApiPropertySignature && member.isOptional) {
|
|
|
|
tags.push('optional')
|
2024-01-15 12:33:15 +00:00
|
|
|
}
|
2024-06-13 13:09:27 +00:00
|
|
|
if (!isComponentProp) {
|
|
|
|
const kind = model.isComponent(member) ? 'component' : member.kind.toLowerCase()
|
|
|
|
tags.push(kind)
|
2024-01-15 12:33:15 +00:00
|
|
|
}
|
2024-02-29 16:28:45 +00:00
|
|
|
result.markdown += `<Small>${tags.filter((t) => t.toLowerCase() !== 'none').join(' ')}</Small>\n\n`
|
2024-01-15 12:33:15 +00:00
|
|
|
}
|
|
|
|
|
2024-06-13 13:09:27 +00:00
|
|
|
function addExtends(result: Result, item: ApiItem) {
|
|
|
|
const extendsTypes =
|
|
|
|
item instanceof ApiClass && item.extendsType
|
|
|
|
? [item.extendsType]
|
|
|
|
: item instanceof ApiInterface
|
|
|
|
? item.extendsTypes
|
|
|
|
: []
|
|
|
|
|
|
|
|
if (!extendsTypes.length) return
|
|
|
|
|
2024-06-13 13:47:13 +00:00
|
|
|
const links = {} as Record<string, string>
|
|
|
|
for (const type of extendsTypes) {
|
|
|
|
for (const token of type.excerpt.spannedTokens) {
|
|
|
|
if (!token.canonicalReference) continue
|
|
|
|
|
|
|
|
const apiItemResult = item
|
|
|
|
.getAssociatedModel()!
|
|
|
|
.resolveDeclarationReference(token.canonicalReference!, item)
|
|
|
|
|
|
|
|
if (apiItemResult.errorMessage) continue
|
|
|
|
|
|
|
|
const apiItem = apiItemResult.resolvedApiItem!
|
|
|
|
links[token.text] = `/reference/${getPath(apiItem)}`
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
result.markdown += [
|
|
|
|
`<CodeLinkProvider links={${JSON.stringify(links)}}>`,
|
|
|
|
'',
|
|
|
|
`Extends \`${extendsTypes.map((type) => type.excerpt.text).join(', ')}\`.`,
|
|
|
|
'',
|
|
|
|
'</CodeLinkProvider>',
|
|
|
|
'',
|
|
|
|
].join('\n')
|
2024-06-13 13:09:27 +00:00
|
|
|
}
|
|
|
|
|
2024-01-15 12:33:15 +00:00
|
|
|
function addLinkToSource(result: Result, member: ApiItem) {
|
|
|
|
if ('_fileUrlPath' in member && member._fileUrlPath) {
|
|
|
|
result.markdown += `<ApiHeading>Source</ApiHeading>\n\n`
|
|
|
|
result.markdown += `[${member._fileUrlPath}](${REPO_URL}${member._fileUrlPath})\n\n`
|
|
|
|
}
|
|
|
|
}
|