import { ParamTag, PropDescriptor } from 'vue-docgen-api' import { escapeCharacter, toKebabCase, unquote, trimStr, cleanStr, } from '../utils' const tmpl = ( props: PropDescriptor[], { isInterface = false }: { isInterface: boolean }, lang: string, ) => { const displayableProps = props // .filter( // ({ name, description, tags }) => // description || ['disabled'].includes(name) || lang in (tags ?? {}) // ); const hasVersion = displayableProps.some((prop) => prop?.tags?.version) const content = displayableProps.map((prop) => { const { name, type, values, defaultValue, required, tags } = prop let { description } = prop if (tags?.[lang]?.length) { description = (tags[lang][0] as ParamTag).description as string } // 支持通过名为 type 的 tag 重新定义字段的类型 const fixedType = cleanStr( // tag 的 ts 类型有问题,所以忽略 ts 规则检查 // @ts-ignore-next-line trimStr(tags?.type?.[0]?.description || type?.name || ''), ) const getName = () => `${ isInterface ? name : toKebabCase(name) }${ tags?.vModel || name === 'modelValue' ? ' **(v-model)**' : '' }${ required ? (lang === 'zh' ? ' **(*)**' : ' **(*)**') : '' }` const getDescription = () => { if (!description && name === 'disabled') { return lang === 'zh' ? '是否禁用' : 'Whether to disable' } return escapeCharacter(trimStr(description || '')) } const getType = () => { if (values) { return escapeCharacter( values .map((item) => { return fixedType === 'string' ? `'${ unquote(item) }'` : item }) .join(' | '), ) } return escapeCharacter(fixedType) } const getDefaultValue = () => { if (tags?.defaultValue) { // @ts-ignore-next-line return tags.defaultValue[0]?.description } if (defaultValue?.value === 'undefined') { return '-' } const regForArrowFunction = /^\(\)\s*=>\s*.*/ if (regForArrowFunction.test(String(defaultValue?.value))) { const returnValue = new Function(`return ${ defaultValue?.value }`)()() return JSON.stringify(returnValue,null,'_-_').replace(/\n/g,'
')?.replace(/_-_/g,'') } // const regForArrayDefaultValue = /^\(\)\s*=>\s*(\[[^]*\]*\])$/ // if ( // (fixedType.includes('[]') || // fixedType.includes('Array') || // fixedType.includes('array')) && // defaultValue?.func && // regForArrayDefaultValue.test(defaultValue.value) // ) { // return cleanStr(defaultValue.value.match(regForArrayDefaultValue)?.[1] || '',) // } if (fixedType === 'boolean') { return cleanStr(defaultValue?.value || 'false') } return defaultValue?.value || '-' } let lineContent = `|${ getName() }|${ getDescription() }|\`${ getType() }\`| ${ getDefaultValue() } |` if (hasVersion) { // tag 的 ts 类型有问题,所以忽略 ts 规则检查 // @ts-ignore-next-line const version = tags?.version?.[0]?.description lineContent += `${ version || '' }|` } return lineContent }) .join('\n') return { hasVersion, content, } } export default ( props: PropDescriptor[], options: { isInterface: boolean }, lang = 'zh', ) => { const { content, hasVersion } = tmpl(props, options, lang) if (!content) return '' let header: [string, string] = ['', ''] if (lang === 'en') { header = options.isInterface ? ['|Name|Description|Type|Default|', '|---|---|---|:---:|'] : ['|Attribute|Description|Type|Default|', '|---|---|---|:---|'] if (hasVersion) { header[0] += 'version|' header[1] += ':---|' } } else { header = ['|参数名|描述|类型|默认值|', '|---|---|---|:---|'] if (hasVersion) { header[0] += '版本|' header[1] += ':---|' } } return ` ${ header[0] } ${ header[1] } ${ content } ` };