UNPKG

@sanity/tsdoc

Version:

Generate API reference docs from TypeScript projects and store in a Sanity-friendly JSON format. Render a static frontend, or as React components.

131 lines (113 loc) 3.96 kB
import {ApiVariable} from '@microsoft/api-extractor-model' import {SanityReferenceValue} from '../_lib/sanity' import {SerializedAPIVariable} from '../types' import {_transformTokens} from './_transformTokens' import {RELEASE_TAGS} from './constants' import {_createExportMemberId, _sanitizeName, _slugify} from './helpers' import {_transformDocComment} from './transformDocComment' import {TransformContext} from './types' /** * @internal */ export function _transformVariable( ctx: TransformContext, node: ApiVariable, ): SerializedAPIVariable { if (!ctx.export) { throw new Error('transformVariable: missing `export` document') } if (!ctx.package) { throw new Error('transformVariable: missing `package` document') } if (!ctx.release) { throw new Error('transformVariable: missing `release` document') } const name = _sanitizeName(node.name) const docComment = node.tsdocComment const comment = docComment ? _transformDocComment(docComment) : undefined const type = _transformTokens( ctx, node.excerptTokens.slice( node.variableTypeExcerpt.tokenRange.startIndex, node.variableTypeExcerpt.tokenRange.endIndex, ), ) const isReactComponentType = _variableIsReactComponentType(node) const propsType = isReactComponentType ? _variablePropsType(ctx, node) : undefined return { _type: 'api.variable', comment, export: {_type: 'reference', _ref: ctx.export._id}, isReactComponentType, name, package: {_type: 'reference', _ref: ctx.package._id}, propsType, release: {_type: 'reference', _ref: ctx.release._id}, releaseTag: RELEASE_TAGS[node.releaseTag], slug: {_type: 'slug', current: _slugify(name)}, type, } } function _variableIsReactComponentType(node: ApiVariable) { const typeTokens = node.excerptTokens.slice( node.variableTypeExcerpt.tokenRange.startIndex, node.variableTypeExcerpt.tokenRange.endIndex, ) const typeCode = typeTokens .map((t) => t.text) .join('') .trim() const isNamedExoticComponent = typeCode.startsWith('React.NamedExoticComponent<') || typeCode.startsWith('React_2.NamedExoticComponent<') || typeCode.startsWith('NamedExoticComponent<') const isForwardRefExoticComponent = typeCode.startsWith('React.ForwardRefExoticComponent<') || typeCode.startsWith('React_2.ForwardRefExoticComponent<') || typeCode.startsWith('ForwardRefExoticComponent<') const isMemoExoticComponent = typeCode.startsWith('React.MemoExoticComponent<') || typeCode.startsWith('React_2.MemoExoticComponent<') || typeCode.startsWith('MemoExoticComponent<') const isStyledComponent = typeCode.startsWith('StyledComponent<') const returnsReactElement = typeCode.endsWith('=> React.ReactElement') || typeCode.endsWith('=> React_2.ReactElement') || typeCode.endsWith('=> ReactElement') || typeCode.endsWith('=> JSX.Element') if ( isNamedExoticComponent || isForwardRefExoticComponent || isMemoExoticComponent || isStyledComponent || returnsReactElement ) { return true } return false } function _variablePropsType( ctx: TransformContext, node: ApiVariable, ): SanityReferenceValue | undefined { const typeTokens = node.excerptTokens.slice( node.variableTypeExcerpt.tokenRange.startIndex, node.variableTypeExcerpt.tokenRange.endIndex, ) const componentRef = typeTokens.find((t) => t.kind === 'Reference' && t.text.endsWith('Props')) if (componentRef && componentRef.canonicalReference) { return { _type: 'reference', _ref: _createExportMemberId(ctx, componentRef.canonicalReference.toString()), } // console.log({ // refString: sanityUIRef.canonicalReference.toString(), // ref: { // _type: 'reference', // _ref: _createExportMemberId(ctx, sanityUIRef.canonicalReference.toString()), // }, // }) // return undefined } return undefined }