Allow dynamic modules for description

This commit is contained in:
the1812 2022-06-18 15:07:25 +08:00
parent 9b70ca2d38
commit f83615bc83
6 changed files with 31 additions and 28 deletions

View File

@ -20,7 +20,7 @@ export const getComponentsDoc: DocSource = async rootPath => {
return undefined
})
.filter(it => it !== undefined)
.map(it => {
.map(async it => {
const root = `${rootPath}components/`
const fullRelativePath = `${root}${getId(root, it.path.replace(/^\.?\//, ''))}.js`
const fullAbsolutePath = fullRelativePath.replace(/^(\.\.?\/)*/, '')
@ -28,7 +28,7 @@ export const getComponentsDoc: DocSource = async rootPath => {
name,
displayName,
} = it.component
const description = getDescriptionMarkdown(it.component)
const description = await getDescriptionMarkdown(it.component)
return {
type: 'component',
name,
@ -41,6 +41,6 @@ export const getComponentsDoc: DocSource = async rootPath => {
.concat(thirdPartyComponents.map(getThirdPartyDescription))
return {
title: '组件',
items: componentsPaths,
items: await Promise.all(componentsPaths),
}
}

View File

@ -20,7 +20,7 @@ export const getPluginsDoc: DocSource = async rootPath => {
return undefined
})
.filter(it => it !== undefined)
.map(it => {
.map(async it => {
const root = `${rootPath}plugins/`
const fullRelativePath = `${root}${getId(root, it.path.replace(/^\.?\//, ''))}.js`
const fullAbsolutePath = fullRelativePath.replace(/^(\.\.?\/)*/, '')
@ -28,7 +28,7 @@ export const getPluginsDoc: DocSource = async rootPath => {
name,
displayName,
} = it.plugin
const description = getDescriptionMarkdown(it.plugin)
const description = await getDescriptionMarkdown(it.plugin)
return {
type: 'plugin',
name,
@ -41,6 +41,6 @@ export const getPluginsDoc: DocSource = async rootPath => {
.concat(thirdPartyPlugins.map(getThirdPartyDescription))
return {
title: '插件',
items: pluginsPaths,
items: await Promise.all(pluginsPaths),
}
}

View File

@ -17,10 +17,10 @@ export const thirdPartyPlugins: DocSourceItem[] = [
]
// FIXME: 在线拉取 metadata 用 getDescriptionMarkdown 生成才能有最完整的信息, 现在这实现只能拿到主 owner, 链接也不能确定
export const getThirdPartyDescription = (item: DocSourceItem) => {
export const getThirdPartyDescription = async (item: DocSourceItem) => {
const ownerText = item.owner ? `by ${item.owner}\n\n` : ''
return {
...item,
description: ownerText + getDescriptionMarkdown(item),
description: ownerText + await getDescriptionMarkdown(item),
}
}

View File

@ -2,6 +2,7 @@ import marked from 'marked'
import { languageNameToCode } from '@/core/utils/i18n'
import { ComponentMetadata } from './component'
import { getSelectedLanguage } from './i18n/helpers'
import { Executable } from '@/core/common-types'
type ItemWithDescription = Pick<ComponentMetadata, 'description' | 'author'>
@ -9,7 +10,7 @@ type ItemWithDescription = Pick<ComponentMetadata, 'description' | 'author'>
* `description` `author`, (Markdown)
* @param item
*/
export const getDescriptionMarkdown = (item: ItemWithDescription) => {
export const getDescriptionMarkdown = async (item: ItemWithDescription) => {
const { description, author } = item
const authorPrefix = (() => {
if (!author) {
@ -20,22 +21,22 @@ export const getDescriptionMarkdown = (item: ItemWithDescription) => {
}
return `by [@${author.name}](${author.link})\n\n`
})()
const descriptionText = (() => {
const descriptionText = await (async () => {
if (!description) {
// if (options && Object.keys(options).length > 0) {
// const count = Object.keys(options).length
// return `${count}个选项`
// }
return '暂无描述.'
// return ''
}
if (typeof description === 'string') {
return description
const parseDescriptionInput = async (input: string | Executable<string>) => {
if (typeof input === 'string') {
return input
}
return input()
}
return (
description[languageNameToCode(getSelectedLanguage())]
|| description['zh-CN']
)
if (typeof description === 'object') {
const currentLanguage = languageNameToCode(getSelectedLanguage())
const input = description[currentLanguage] ?? description['zh-CN']
return parseDescriptionInput(input)
}
return parseDescriptionInput(description)
})()
return authorPrefix + descriptionText
}
@ -44,15 +45,15 @@ export const getDescriptionMarkdown = (item: ItemWithDescription) => {
* `getDescriptionMarkdown`, Markdown HTML string
* @param item
*/
export const getDescriptionHTML = (item: ItemWithDescription) => marked(
getDescriptionMarkdown(item),
export const getDescriptionHTML = async (item: ItemWithDescription) => marked(
await getDescriptionMarkdown(item),
)
/**
* `getDescriptionMarkdown`, Markdown (innerText)
* @param item
*/
export const getDescriptionText = (item: ItemWithDescription) => {
const html = getDescriptionHTML(item)
export const getDescriptionText = async (item: ItemWithDescription) => {
const html = await getDescriptionHTML(item)
const div = document.createElement('div')
div.innerHTML = html
return div.innerText

View File

@ -212,6 +212,8 @@ export interface FunctionalMetadata<
urlInclude?: TestPattern
/** 设置不匹配的URL, 不匹配则不运行此组件, 优先级高于`urlInclude` */
urlExclude?: TestPattern
/** i18n 数据 */
i18n?: Record<string, LanguagePack | Executable<LanguagePack>>
}
/** ComponentMetadata 的类型参数,用于表达其可选参数 options 的类型 */
@ -237,8 +239,6 @@ export interface ComponentMetadata<
hidden?: boolean
/** 组件子选项 */
options?: Om
/** i18n 数据 */
i18n?: Record<string, LanguagePack | Executable<LanguagePack>>
/** 是否支持热重载 */
// allowHotReload?: boolean
}

View File

@ -12,7 +12,9 @@ export type VueModule =
| { default: Component }
| VueConstructor
| { default: VueConstructor }
export type I18nDescription = string | { 'zh-CN': string; [key: string]: string }
type DescriptionInput = string | Executable<string>
export type I18nDescription = DescriptionInput | { 'zh-CN': DescriptionInput; [key: string]: DescriptionInput }
export type WithName = {
name: string
displayName: string