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

View File

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

View File

@ -17,10 +17,10 @@ export const thirdPartyPlugins: DocSourceItem[] = [
] ]
// FIXME: 在线拉取 metadata 用 getDescriptionMarkdown 生成才能有最完整的信息, 现在这实现只能拿到主 owner, 链接也不能确定 // FIXME: 在线拉取 metadata 用 getDescriptionMarkdown 生成才能有最完整的信息, 现在这实现只能拿到主 owner, 链接也不能确定
export const getThirdPartyDescription = (item: DocSourceItem) => { export const getThirdPartyDescription = async (item: DocSourceItem) => {
const ownerText = item.owner ? `by ${item.owner}\n\n` : '' const ownerText = item.owner ? `by ${item.owner}\n\n` : ''
return { return {
...item, ...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 { languageNameToCode } from '@/core/utils/i18n'
import { ComponentMetadata } from './component' import { ComponentMetadata } from './component'
import { getSelectedLanguage } from './i18n/helpers' import { getSelectedLanguage } from './i18n/helpers'
import { Executable } from '@/core/common-types'
type ItemWithDescription = Pick<ComponentMetadata, 'description' | 'author'> type ItemWithDescription = Pick<ComponentMetadata, 'description' | 'author'>
@ -9,7 +10,7 @@ type ItemWithDescription = Pick<ComponentMetadata, 'description' | 'author'>
* `description` `author`, (Markdown) * `description` `author`, (Markdown)
* @param item * @param item
*/ */
export const getDescriptionMarkdown = (item: ItemWithDescription) => { export const getDescriptionMarkdown = async (item: ItemWithDescription) => {
const { description, author } = item const { description, author } = item
const authorPrefix = (() => { const authorPrefix = (() => {
if (!author) { if (!author) {
@ -20,22 +21,22 @@ export const getDescriptionMarkdown = (item: ItemWithDescription) => {
} }
return `by [@${author.name}](${author.link})\n\n` return `by [@${author.name}](${author.link})\n\n`
})() })()
const descriptionText = (() => { const descriptionText = await (async () => {
if (!description) { if (!description) {
// if (options && Object.keys(options).length > 0) {
// const count = Object.keys(options).length
// return `${count}个选项`
// }
return '暂无描述.' return '暂无描述.'
// return ''
} }
if (typeof description === 'string') { const parseDescriptionInput = async (input: string | Executable<string>) => {
return description if (typeof input === 'string') {
return input
}
return input()
} }
return ( if (typeof description === 'object') {
description[languageNameToCode(getSelectedLanguage())] const currentLanguage = languageNameToCode(getSelectedLanguage())
|| description['zh-CN'] const input = description[currentLanguage] ?? description['zh-CN']
) return parseDescriptionInput(input)
}
return parseDescriptionInput(description)
})() })()
return authorPrefix + descriptionText return authorPrefix + descriptionText
} }
@ -44,15 +45,15 @@ export const getDescriptionMarkdown = (item: ItemWithDescription) => {
* `getDescriptionMarkdown`, Markdown HTML string * `getDescriptionMarkdown`, Markdown HTML string
* @param item * @param item
*/ */
export const getDescriptionHTML = (item: ItemWithDescription) => marked( export const getDescriptionHTML = async (item: ItemWithDescription) => marked(
getDescriptionMarkdown(item), await getDescriptionMarkdown(item),
) )
/** /**
* `getDescriptionMarkdown`, Markdown (innerText) * `getDescriptionMarkdown`, Markdown (innerText)
* @param item * @param item
*/ */
export const getDescriptionText = (item: ItemWithDescription) => { export const getDescriptionText = async (item: ItemWithDescription) => {
const html = getDescriptionHTML(item) const html = await getDescriptionHTML(item)
const div = document.createElement('div') const div = document.createElement('div')
div.innerHTML = html div.innerHTML = html
return div.innerText return div.innerText

View File

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

View File

@ -12,7 +12,9 @@ export type VueModule =
| { default: Component } | { default: Component }
| VueConstructor | VueConstructor
| { default: 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 = { export type WithName = {
name: string name: string
displayName: string displayName: string