docs: add contributors

This commit is contained in:
Jiwen Bai 2023-05-25 15:00:11 +08:00
parent f00d90cdef
commit 61c22e471e
10 changed files with 256 additions and 5 deletions

1
.gitignore vendored
View File

@ -23,6 +23,7 @@ es
*.tsbuildinfo
pnpm-lock.yaml
web-types.json
*.meta.json
~*
.pnpm-debug.log
.history

View File

@ -169,6 +169,10 @@ async function convertMd2ComponentDocumentation (
url,
env = 'development'
) {
let componentName = null
if (/^src\/[\w-]+\/demos\/\w+\/index.demo-entry.md/.test(url)) {
componentName = url.split('/')[1]
}
const forceShowAnchor = !!~text.search('<!--anchor:on-->')
const colSpan = ~text.search('<!--single-column-->') ? 1 : 2
const hasApi = !!~text.search('## API')
@ -224,6 +228,10 @@ async function convertMd2ComponentDocumentation (
gfm: true,
renderer: mdRenderer
})
// doc contributors
const docContributorsTemplate = componentName
? `<Contributors name="${componentName}" />`
: ''
// generate page
const docTemplate = `
<template>
@ -233,6 +241,7 @@ async function convertMd2ComponentDocumentation (
>
<div :style="contentStyle">
${docMainTemplate}
${docContributorsTemplate}
</div>
<div style="width: 192px;" v-if="showAnchor">
${

View File

@ -0,0 +1,43 @@
const componentsList = require('../../components.meta.json')
const componentsCommits = require('../../components-commits.meta.json')
const CONR_ID = '/virtual-contributors'
function getContributorsAt (component) {
try {
const componentCommits = componentsCommits[component]
const map = {}
componentCommits
.filter((i) => i.author)
.forEach((i) => {
const login = i.author?.user?.login
if (login === undefined) {
return
}
if (!map[login]) {
map[login] = {
name: login,
count: 0,
avatar: i.author?.avatarUrl
}
}
map[login].count++
})
return Object.values(map).sort((a, b) => b.count - a.count)
} catch (e) {
console.error(e)
return []
}
}
function getComponentContributors () {
const result = componentsList.map((component) => {
return [component, getContributorsAt(component)]
})
return Object.fromEntries(result)
}
module.exports = {
getComponentContributors,
CONR_ID
}

View File

@ -0,0 +1,18 @@
const { CONR_ID } = require('./utils/virtual-contributors')
function createContributorsPlugin (data) {
return {
name: 'virtual-contributors',
resolveId (id) {
return id === CONR_ID ? CONR_ID : null
},
load (id) {
if (id !== CONR_ID) {
return null
}
return `export default ${JSON.stringify(data)}`
}
}
}
module.exports = createContributorsPlugin

View File

@ -2,6 +2,8 @@ const createVuePlugin = require('@vitejs/plugin-vue')
const getTransformedVueSrc = require('./utils/get-demo-by-path')
const createCssrPlugin = require('./vite-plugin-css-render')
const siteIndexTransFormPlugin = require('./vite-plugin-index-tranform')
const createContributorsPlugin = require('./vite-plugin-contributors')
const { getComponentContributors } = require('./utils/virtual-contributors')
const fileRegex = /\.(md|vue)$/
@ -10,6 +12,9 @@ const vuePlugin = createVuePlugin({
})
const createDemoPlugin = () => {
// const contributors = process.env.NODE_ENV === 'production' ? getComponentContributors() : {}
const contributors = getComponentContributors()
const naiveDemoVitePlugin = {
name: 'demo-vite',
transform (_, id) {
@ -30,8 +35,14 @@ const createDemoPlugin = () => {
}
const cssrPlugin = createCssrPlugin()
return [siteIndexTransFormPlugin, naiveDemoVitePlugin, vuePlugin, cssrPlugin]
const plugins = [
siteIndexTransFormPlugin,
naiveDemoVitePlugin,
createContributorsPlugin(contributors),
vuePlugin,
cssrPlugin
]
return plugins
}
module.exports = createDemoPlugin

View File

@ -1,6 +1,7 @@
import ComponentDemo from './utils/ComponentDemo.vue'
import ComponentDemos from './utils/ComponentDemos'
import EditOnGithubHeader from './utils/EditOnGithubHeader.vue'
import Contributors from './utils/Contributors.vue'
import './styles/demo.css'
import 'vfonts/Inter.css'
import 'vfonts/FiraCode.css'
@ -10,4 +11,5 @@ export function installDemoComponents (app) {
app.component('ComponentDemo', ComponentDemo)
app.component('ComponentDemos', ComponentDemos)
app.component('EditOnGithubHeader', EditOnGithubHeader)
app.component('Contributors', Contributors)
}

View File

@ -0,0 +1,37 @@
<template>
<n-h3> Contributors </n-h3>
<n-space>
<div v-for="author in contributors" :key="author.avatar">
<n-tooltip>
<template #trigger>
<a
style="display: block"
target="_blank"
:href="`https://github.com/${author.name}`"
>
<n-avatar size="small" round :src="author.avatar" />
</a>
</template>
{{ author.name }}
</n-tooltip>
</div>
</n-space>
</template>
<script lang="ts" setup>
// @ts-expect-error missing types
// eslint-disable-next-line import/no-absolute-path
import _contributors from '/virtual-contributors'
import { computed } from 'vue'
const props = defineProps<{ name: string }>()
const contributors = computed(
() =>
(_contributors[props.name] &&
_contributors[props.name].map((c: any) => {
return c
})) ||
([] as any[])
)
</script>

View File

@ -9,8 +9,8 @@
"jsdelivr": "dist/index.js",
"scripts": {
"start": "pnpm run dev",
"dev": "pnpm run clean && pnpm run gen-version && pnpm run gen-volar-dts && NODE_ENV=development vite",
"build:package": "pnpm run gen-version && pnpm run clean && pnpm run gen-volar-dts && tsc -b --force tsconfig.esm.json && node scripts/pre-build/pre-cjs-build.js && tsc -b --force tsconfig.cjs.json && rollup -c && pnpm run test:umd && node scripts/post-build && rimraf {es,lib}/*.tsbuildinfo",
"dev": "pnpm run clean && pnpm run gen-version && pnpm run gen-components &&pnpm run gen-volar-dts && NODE_ENV=development vite --host",
"build:package": "pnpm run gen-version && pnpm run clean && pnpm run gen-components && pnpm run github-commits && pnpm run gen-volar-dts && tsc -b --force tsconfig.esm.json && node scripts/pre-build/pre-cjs-build.js && tsc -b --force tsconfig.cjs.json && rollup -c && pnpm run test:umd && node scripts/post-build && rimraf {es,lib}/*.tsbuildinfo",
"build:site": "./scripts/pre-build-site/pre-build-site.sh && NODE_ENV=production NODE_OPTIONS=--max-old-space-size=4096 vite build && ./scripts/post-build-site/post-build-site.sh",
"clean": "rimraf site lib es dist node_modules/naive-ui themes/tusimple/es themes/tusimple/lib",
"release:package": "pnpm run test && pnpm run build:package && pnpm publish --no-git-checks",
@ -30,6 +30,8 @@
"test:watch": "NODE_ENV=test jest ---watch --verbose --coverage",
"test:umd": "jest --collectCoverage=false --testMatch=\"<rootDir>/umd-test/index.spec.js\"",
"gen-version": "node scripts/gen-version",
"gen-components": "node scripts/gen-components-list",
"gen-github-commits": "node scripts/gen-github-commits",
"gen-volar-dts": "esbuild scripts/gen-component-declaration.js --bundle --platform=node --tsconfig=tsconfig.esbuild.json | node",
"build:site:ts": "./scripts/pre-build-site/pre-build-site.sh && TUSIMPLE=true NODE_ENV=production NODE_OPTIONS=--max-old-space-size=4096 vite build && ./scripts/post-build-site/post-build-site.sh",
"prepare": "husky install",
@ -156,7 +158,10 @@
"highlight.js": "^11.5.0",
"lodash": "^4.17.21",
"lodash-es": "^4.17.21",
"md5": "^2.3.0",
"octokit": "^2.0.18",
"seemly": "^0.3.6",
"simple-git": "^3.18.0",
"treemate": "^0.3.11",
"vdirs": "^0.1.8",
"vooks": "^0.2.12",
@ -185,4 +190,4 @@
]
}
}
}
}

View File

@ -0,0 +1,21 @@
const path = require('path')
const fg = require('fast-glob')
const fs = require('fs-extra')
async function listComponents () {
const files = await fg('*', {
onlyDirectories: true,
cwd: path.join(__dirname, '../src'),
ignore: ['_*', 'dist', 'node_modules']
})
files.sort()
return files
}
async function updateComponentsList () {
const componentList = await listComponents()
fs.writeJSON(path.join(__dirname, '../components.meta.json'), componentList, {
spaces: 2
})
}
updateComponentsList()

View File

@ -0,0 +1,104 @@
const componentsList = require('../components.meta.json')
const { Octokit } = require('octokit')
const fs = require('fs')
const path = require('path')
const REPO_OWNER = 'tusen-ai'
const REPO_NAME = 'naive-ui'
const REPO_BRANCH = 'main'
const octokit = new Octokit({
auth: process.env.GITHUB_TOKEN
})
async function fetchCommits (options) {
const query = `{
repository(owner: "${REPO_OWNER}", name: "${REPO_NAME}") {
object(expression: "${REPO_BRANCH}") {
... on Commit {
${options
.map(({ path, after }, index) => {
return `
path${index}: history(path: "${path}"${
after ? `, after: "${after}"` : ''
}) {
nodes {
oid
author {
avatarUrl
date
email
name
user {
login
}
}
}
pageInfo {
hasNextPage
endCursor
}
}`
})
.join('\n')}
}
}
}
}`
const response = (await octokit.graphql(query)).repository.object
return Object.fromEntries(
Object.entries(response).map(([key, result]) => {
const index = +key.replace('path', '')
return [index, result]
})
)
}
async function getComponentsCommits (components) {
let options = components.map((component) => {
return { key: component, path: `src/${component}` }
})
const commits = {}
do {
const results = await fetchCommits(options)
for (const [i, result] of Object.values(results).entries()) {
const component = options[i].key
if (!commits[component]) commits[component] = []
commits[component].push(...result.nodes)
}
options = options
.map((option, index) => {
const pageInfo = results[index].pageInfo
const after = pageInfo.hasNextPage ? pageInfo.endCursor : undefined
return { ...option, after }
})
.filter((option) => !!option.after && commits[option.key].length < 200)
} while (options.length > 0)
return commits
}
const taskComponents = []
for (let i = 0; i < componentsList.length; i++) {
if (i % 5 === 0) {
taskComponents.push(componentsList.slice(i, i + 5))
}
}
async function getAllComponentsCommits () {
const componentsCommits = {}
const promiseAll = []
for (const task of taskComponents) {
promiseAll.push(getComponentsCommits(task))
}
const results = await Promise.all(promiseAll)
for (const commits of results) {
Object.assign(componentsCommits, commits)
}
fs.writeFileSync(
path.resolve(__dirname, '../components-commits.meta.json'),
JSON.stringify(componentsCommits, null, 2)
)
}
getAllComponentsCommits()