-
Notifications
You must be signed in to change notification settings - Fork 117
feat(contributors): add contributors section to documentation and scripts for automatic updates #424
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…ipts for automatic updates - Added a new `DocContributors` component to display contributors in documentation. - Updated multiple component documentation files to include a contributors section. - Introduced scripts for collecting and updating contributor data automatically. - Added a new entry in `package.json` for updating contributors.
✅ Deploy Preview for antd-design-x-vue ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
Caution Review failedThe pull request is closed. WalkthroughAdds contributor datasets (JSON + generated TS), a DocContributors Vue component registered in VitePress, updates many component docs to embed the widget, and introduces scripts to collect, generate, and insert contributor sections plus an npm script to run updates. Changes
Sequence Diagram(s)sequenceDiagram
participant Reader as Docs Reader
participant Page as VitePress Page
participant Widget as DocContributors.vue
participant Data as contributors/data.ts
Reader->>Page: Open component docs
Page->>Widget: render (SSR)
Note over Widget: SSR returns empty / placeholder
Reader->>Widget: client hydration
Widget->>Data: dynamic import()
Data-->>Widget: contributorsData
Widget->>Widget: aggregate by componentName / files, sort, slice
Widget-->>Reader: render avatars and links
sequenceDiagram
participant Dev as Developer
participant NPM as npm
participant Updater as scripts/update-contributors.js
participant Collector as scripts/collect-contributors.js
participant Git as git
participant GH as GitHub API
participant FS as File System
Dev->>NPM: npm run update-contributors
NPM->>Updater: exec collect script
Updater->>Collector: start collection
Collector->>Git: git log per component/file
Git-->>Collector: author lists & counts
Collector->>GH: fetch /contributors
GH-->>Collector: repo contributors (or fallback)
Collector->>FS: write contributors/contributors.json
Collector->>FS: write contributors/data.ts
Collector-->>Updater: done
Updater-->>Dev: completed
Estimated code review effort🎯 4 (Complex) | ⏱️ ~35 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (16)
✨ Finishing Touches
🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
|
同 Element Plus 方案区别,Element Plus 项目通过 GitHub GraphQL API 获取数据 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 5
🧹 Nitpick comments (12)
package.json (1)
31-31: Add docs updater to the workflow (optional)Consider chaining the docs injection step into update-contributors, or expose it as a separate npm script for convenience.
Proposed options:
Option A: Chain both steps
- "update-contributors": "node scripts/update-contributors.js", + "update-contributors": "node scripts/update-contributors.js && node scripts/add-contributors-to-docs.js",Option B: Add a separate script
"typecheck": "vue-tsc --noEmit", "update-contributors": "node scripts/update-contributors.js", + "docs:add-contributors": "node scripts/add-contributors-to-docs.js", "play": "vite ./play"scripts/add-contributors-to-docs.js (4)
10-21: Broaden component coverage to match actual docsThe array misses some components that already have contributors sections in this PR (e.g., bubble, sender, welcome). Keep the list in sync to avoid manual drift.
const components = [ { file: 'attachments.md', name: 'attachments' }, + { file: 'bubble.md', name: 'bubble' }, { file: 'conversations.md', name: 'conversations' }, { file: 'prompts.md', name: 'prompts' }, + { file: 'sender.md', name: 'sender' }, { file: 'suggestion.md', name: 'suggestion' }, { file: 'thought-chain.md', name: 'thought-chain' }, { file: 'use-x-agent.md', name: 'use-x-agent' }, { file: 'use-x-chat.md', name: 'use-x-chat' }, + { file: 'welcome.md', name: 'welcome' }, { file: 'x-provider.md', name: 'x-provider' }, { file: 'x-request.md', name: 'x-request' }, { file: 'x-stream.md', name: 'x-stream' } ]
37-41: Make the “already has contributors” check more robustCurrent includes() checks can miss variations (case, whitespace, attributes order). Use regexes anchored to headings and tags.
- // 检查是否已经有贡献者部分 - if (content.includes('## 贡献者') || content.includes('<doc-contributors')) { - console.log(`⏭️ ${filename} already has contributors section`) - return false - } + // 检查是否已经有贡献者部分(更鲁棒) + const hasContributors = + /(^|\n)##\s*贡献者\b/i.test(content) || + /<doc-contributors\b/i.test(content) + if (hasContributors) { + console.log(`⏭️ ${filename} already has contributors section`) + return false + }
78-81: Tweak final reminder message (nit)In this repo, DocContributors is already registered in docs/.vitepress/vitepress/index.ts. The reminder could be misleading; either remove or conditionally log it.
- console.log('\n🎉 Contributors sections added successfully!') - console.log('💡 Remember to register the doc-contributors component in your VitePress theme.') + console.log('\n🎉 Contributors sections added successfully!') + console.log('💡 DocContributors is already registered in docs/.vitepress/vitepress/index.ts.')
57-87: Optional: add CLI options for dry-run and custom targetsNot required, but a simple CLI improves safety and reusability:
- --dry-run: don’t write files, just report
- --dir : override docsDir
- --only : process a subset
Example approach (outside current lines; for illustration only):
// At top: const argv = require('node:util').parseArgs?.({ options: { 'dry-run': { type: 'boolean' }, dir: { type: 'string' }, only: { type: 'string' } }, })?.values || {}; const DRY = !!argv['dry-run']; const docsDir = path.resolve(argv.dir || path.join(__dirname, '../docs/component')); const onlySet = argv.only ? new Set(argv.only.split(',').map(s => s.trim())) : null; // In processFile before write: if (DRY) { console.log(`🔎 (dry-run) Would add contributors to ${filename}`); return true; } // In addContributorsToAllDocs loop: (onlySet ? components.filter(c => onlySet.has(c.name) || onlySet.has(c.file)) : components).forEach(...)docs/component/use-x-agent.md (1)
110-110: Optional: wrap with ClientOnly if SSR hydration warnings appear.DocContributors loads data client-side; if SSR renders placeholders and causes hydration diffs, wrap with ClientOnly.
-<doc-contributors component-name="use-x-agent" :max-count="6" :show-view-all="true" /> +<ClientOnly> + <doc-contributors component-name="use-x-agent" :max-count="6" :show-view-all="true" /> +</ClientOnly>scripts/update-contributors.js (2)
4-4: Remove unused importThe
pathmodule is imported but never used in this file.const { execSync } = require('child_process') -const path = require('path')
21-21: Add newline at end of fileFiles should end with a newline character for POSIX compliance.
process.exit(1) -} +} +docs/.vitepress/vitepress/components/DocContributors.vue (1)
199-199: Remove debug console.log statementsConsole.log statements should be removed or replaced with proper logging for production code.
- console.log(`Contributors data loaded for component: ${props.componentName}`, data) - console.log(`DocContributors mounted for component: ${props.componentName}`)Also applies to: 208-208
scripts/collect-contributors.js (2)
8-10: Use modern fetch approachThe global fetch polyfill pattern is deprecated. Modern Node.js (18+) has native fetch support.
-// 支持fetch polyfill -if (typeof fetch === 'undefined') { - global.fetch = require('node-fetch') -} +// For Node.js < 18, use node-fetch directly +const fetch = globalThis.fetch || require('node-fetch')
188-196: Weak hash function for ID generationThe simple hash function could produce collisions. Consider using a cryptographic hash or UUID for unique IDs.
+ const crypto = require('crypto') + // 简单的字符串哈希函数 hashCode(str) { - let hash = 0 - for (let i = 0; i < str.length; i++) { - const char = str.charCodeAt(i) - hash = ((hash << 5) - hash) + char - hash = hash & hash // 转换为32位整数 - } - return Math.abs(hash) + // Use crypto for more reliable hashing + return parseInt(crypto.createHash('sha256').update(str).digest('hex').substring(0, 8), 16) }contributors/data.ts (1)
1425-1425: Missing newline at end of fileTypeScript files should end with a newline character.
] } +
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (21)
contributors/contributors.json(1 hunks)contributors/data.ts(1 hunks)docs/.vitepress/vitepress/components/DocContributors.vue(1 hunks)docs/.vitepress/vitepress/index.ts(1 hunks)docs/component/attachments.md(1 hunks)docs/component/bubble.md(1 hunks)docs/component/conversations.md(1 hunks)docs/component/prompts.md(1 hunks)docs/component/sender.md(1 hunks)docs/component/suggestion.md(1 hunks)docs/component/thought-chain.md(1 hunks)docs/component/use-x-agent.md(1 hunks)docs/component/use-x-chat.md(1 hunks)docs/component/welcome.md(1 hunks)docs/component/x-provider.md(1 hunks)docs/component/x-request.md(1 hunks)docs/component/x-stream.md(1 hunks)package.json(1 hunks)scripts/add-contributors-to-docs.js(1 hunks)scripts/collect-contributors.js(1 hunks)scripts/update-contributors.js(1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (6)
docs/component/attachments.md (1)
src/attachments/interface.ts (1)
AttachmentsProps(124-150)
docs/component/welcome.md (1)
src/welcome/style/index.ts (2)
ComponentToken(6-6)WelcomeToken(8-8)
scripts/update-contributors.js (2)
scripts/collect-contributors.js (2)
require(3-3)path(5-5)scripts/add-contributors-to-docs.js (1)
path(4-4)
docs/component/prompts.md (2)
src/prompts/style/index.ts (1)
PromptsToken(8-8)src/prompts/interface.ts (1)
PromptsProps(41-96)
scripts/collect-contributors.js (1)
scripts/update-contributors.js (2)
require(3-3)path(4-4)
contributors/data.ts (2)
src/conversations/interface.ts (1)
ConversationsProps(56-116)src/theme/components.ts (1)
ComponentTokenMap(11-21)
🔇 Additional comments (16)
docs/component/suggestion.md (1)
79-81: Contributors Section ReviewThe
<doc-contributors>invocation indocs/component/suggestion.mdcorrectly uses the registered global component name in kebab-case and is placed appropriately.Please verify the following before merging:
- Every
component-nameused indocs/component/*.mdhas a corresponding key incontributors/data.ts.- Email fields in your contributor data (e.g. in
contributors/data.ts) are not rendered byDocContributors.vue(no PII leaks).docs/component/x-provider.md (1)
48-50: Contributors section added — consistent with othersComponent name and usage look correct.
docs/component/bubble.md (1)
221-223: Contributors section added — LGTMKebab-case component-name aligns with DocContributors registration.
docs/component/welcome.md (1)
69-71: Contributors section added — LGTMMatches the established pattern; no issues spotted.
docs/component/thought-chain.md (1)
128-130: Contributors section added — LGTMHyphenated component-name is consistent with dataset keys used elsewhere.
docs/.vitepress/vitepress/index.ts (1)
4-10: Global registration looks correctImport path and globals registration are correct; in markdown resolves to the PascalCase component name.
docs/component/use-x-agent.md (2)
108-110: Contributors section integration looks correct.Kebab-case props map to componentName/maxCount in Vue. Placement after API is consistent with other docs.
110-110: VerifyshowViewAllprop on the DocContributors componentI couldn’t locate the
DocContributorscomponent file via automated search—please manually confirm:
- In your component definition (e.g.
DocContributors.vueor wherever you register this tag), that you’ve declared ashowViewAll(orshow-view-all) prop viadefineProps()orprops: { … }.- That
contributorsData.componentContributors(incontributors/data.ts) includes a{ component: "use-x-agent", … }entry (this part is already present at line 1010).Once you’ve verified these, this tag usage will work as expected.
docs/component/use-x-chat.md (1)
84-86: Confirmed contributors data for use-x-chat existsThe contributors data file includes an entry for
"component": "use-x-chat", so the<doc-contributors>block will populate as expected.• contributors/data.ts, line 1026:
"component": "use-x-chat"docs/component/x-request.md (1)
89-91: LGTM — Contributors section placement and data verifiedI’ve confirmed that the
x-requestentry exists incomponentContributors(data.ts, line 978), so the contributors list will render correctly. No further changes needed.docs/component/conversations.md (1)
118-120: Approve snippet; data key verifiedThe “conversations” key is present in the contributors dataset (data.ts:817), so the added snippet in docs/component/conversations.md is correct as-is. There are no data-alignment or SSR concerns at this time.
• docs/component/conversations.md (lines 118–120): snippet is valid
• No additional changes required—only wrap<doc-contributors>in<ClientOnly>if you later observe hydration warnings during SSR.docs/component/attachments.md (1)
138-140: Contributors data entry confirmedFound an entry for
"component": "attachments"in data.ts (line 765), so the contributors widget will render correctly without hitting the “no data” fallback.docs/component/prompts.md (1)
116-118: Approved: “prompts” key verified in componentContributors mapping
Found"component": "prompts"in data.ts (line 869). No further action required.docs/component/x-stream.md (1)
60-62: Contributors Block for “x-stream” VerifiedThe lookup in data.ts confirms that the
"x-stream"key is present (line 994), so the new contributors block will render correctly.– data.ts:994 —
"component": "x-stream",docs/component/sender.md (1)
245-247: Approved pending prop verification; confirmshowViewAllsupport on DocContributors
- ✅
data.tsincludes"component": "sender"(line 670) — mapping is present.- ❓ Could not locate
DocContributors.vuein the repo to verify its props. Please ensure the component declares ashowViewAllprop (kebab-caseshow-view-all) to match usage indocs/component/sender.md.contributors/contributors.json (1)
1-1373: LGTM!The auto-generated JSON data file is properly formatted and contains the expected contributor information structure.
| const openProfile = (url: string) => { | ||
| window.open(url, '_blank') | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Validate URL before opening
Opening external URLs without validation could pose a security risk. Consider validating that the URL is from github.com domain.
const openProfile = (url: string) => {
+ // Validate that the URL is from GitHub
+ try {
+ const urlObj = new URL(url)
+ if (!urlObj.hostname.endsWith('github.com')) {
+ console.error('Invalid GitHub URL')
+ return
+ }
+ } catch {
+ console.error('Invalid URL format')
+ return
+ }
window.open(url, '_blank')
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const openProfile = (url: string) => { | |
| window.open(url, '_blank') | |
| } | |
| const openProfile = (url: string) => { | |
| // Validate that the URL is from GitHub | |
| try { | |
| const urlObj = new URL(url) | |
| if (!urlObj.hostname.endsWith('github.com')) { | |
| console.error('Invalid GitHub URL') | |
| return | |
| } | |
| } catch { | |
| console.error('Invalid URL format') | |
| return | |
| } | |
| window.open(url, '_blank') | |
| } |
🤖 Prompt for AI Agents
In docs/.vitepress/vitepress/components/DocContributors.vue around lines
184-186, the openProfile function currently opens any URL directly; validate and
sanitize the input first by constructing a URL object inside a try/catch and
confirm its hostname endsWith 'github.com' (or equals 'github.com') to restrict
to GitHub profiles, and only then call window.open; if validation fails log/warn
or no-op. Also use window.open with safe window features (e.g.
noopener,noreferrer) to avoid exposing the opener.
docs/component/use-x-chat.md
Outdated
| | message | 当前消息的内容 | AgentMessage | - | - | | ||
| ## 贡献者 | ||
|
|
||
| <doc-contributors component-name="use-x-chat" :max-count="6" :show-view-all="true" /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
Confirm showViewAll prop exists on DocContributors.
Same note as other pages; unknown props are ignored in Vue, so ensure it’s declared to render the “view all” UI.
🏁 Script executed:
#!/bin/bash
set -euo pipefail
fd -a "DocContributors.vue" docs | xargs rg -n "showViewAll|show-view-all" || trueLength of output: 1749
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Locate DocContributors.vue
file=$(fd DocContributors.vue || true)
echo "Found file: $file"
# Show props definition context
rg -n "export default" "$file" -A5 -B2 || true
rg -n "props" "$file" -A5 -B2 || true
# Search specifically for showViewAll prop
rg -n "showViewAll" "$file" || true
rg -n "show-view-all" "$file" || trueLength of output: 389
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "1. Searching for doc-contributors.vue files:"
fd -e vue -i "doc-contributors.vue" || echo "> No matching .vue file found"
echo -e "\n2. Searching all .vue files for '<doc-contributors' usages:"
rg -l "<doc-contributors" --glob "*.vue" || echo "> No .vue file contains <doc-contributors>"
echo -e "\n3. Searching for any .vue file defining or exporting 'DocContributors':"
rg -l "name[:=]\s*['\"]DocContributors['\"]" -t vue -g "*.vue" || echo "> No component named DocContributors found"
echo -e "\n4. Searching for 'DocContributors' across JS/TS source files:"
rg -l "DocContributors" -g "*.js" -g "*.ts" -g "*.tsx" || echo "> No references in JS/TS files"Length of output: 1061
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "🔍 Searching for .vitepress directories in the repo..."
vitepress_dirs=$(fd --type d --max-depth 4 ".vitepress" || true)
if [ -z "$vitepress_dirs" ]; then
echo "> No .vitepress directories found"
exit 0
fi
echo "> Found .vitepress dirs:"
printf "%s\n" "$vitepress_dirs"
# For each .vitepress folder, look for theme/components and DocContributors definitions
while IFS= read -r dir; do
comp_dir="$dir/theme/components"
echo -e "\n📁 Checking $comp_dir"
if [ -d "$comp_dir" ]; then
echo " - Searching for DocContributors.vue:"
fd -H -e vue "DocContributors.vue" "$comp_dir" || echo " > None found"
echo " - Searching for props in any DocContributors file:"
rg -n "showViewAll" "$comp_dir" || echo " > No showViewAll references"
rg -n "show-view-all" "$comp_dir" || echo " > No show-view-all references"
else
echo " > No theme/components directory here"
fi
done <<< "$vitepress_dirs"Length of output: 298
#!/bin/bash
set -euo pipefail
echo "🔍 Including hidden directories in search for .vitepress and .vuepress:"
echo "- .vitepress dirs:"
fd -H -t d ".vitepress" || echo " > none found"
echo "- .vuepress dirs:"
fd -H -t d ".vuepress" || echo " > none found"🌐 Web query:
Does the default VitePress DocContributors.vue component define a prop named showViewAll (or show-view-all)? Provide details on its props.
💡 Result:
No. The default VitePress DocContributors.vue component does not define a prop named showViewAll (or show-view-all). It does not expose a prop to toggle a “View all” control; that behavior isn’t part of its public API in the default theme.[10]
Essential details on its props:
- The default theme’s components (including DocContributors) are internal implementation details and not documented as public, stable APIs. VitePress encourages overriding via slots/theme extension rather than relying on undocumented component props.[10][5]
- There is no official documentation listing a showViewAll/show-view-all prop for DocContributors. When a prop isn’t documented in the theme API, you should assume it’s not supported and can change without notice.[10]
What to do instead:
- If you need a “View all contributors” UI or to customize the contributors block, override the theme layout or provide your own component in a custom theme rather than depending on a non-existent prop on DocContributors.[5][10]
Citations:
- 1: No way to input multiline data into Vue Component vuejs/vitepress#423
- 2: https://developer.vonage.com/en/blog/create-a-static-site-using-vitepress-for-beautiful-help-documentation
- 3: https://dev.to/markliu2013/building-vue3-component-library-from-scratch-9-setting-up-and-deploying-documentation-with-vitepress-1hgc
- 4: https://vuejs.org/guide/components/props
- 5: https://vitepress.dev/guide/using-vue
- 6: https://strapi.io/integrations/vitepress
- 7: https://adocs.vercel.app/guide.html
- 8: https://vuejs.org/guide/essentials/component-basics
- 9: https://www.youtube.com/watch?v=Gx2aMCwQ3Rg
- 10: https://github.com/vuejs/vitepress
DocContributors has no showViewAll prop by default – the prop will be ignored
The built-in VitePress DocContributors component does not expose a showViewAll (or show-view-all) prop, so passing it here has no effect. To surface a “View all” link you must extend or override the component in your own theme (e.g. add a props: { showViewAll: Boolean } and render the link), or implement a custom wrapper component. Otherwise you should remove the unused prop.
• Location: docs/component/use-x-chat.md:86
• Action: remove :show-view-all="true" or supply your own themed component under .vitepress/theme/components/DocContributors.vue to support it.
🤖 Prompt for AI Agents
In docs/component/use-x-chat.md around line 86, the DocContributors component is
being passed a non-existent prop :show-view-all="true" which will be ignored;
remove the unused prop from the component invocation OR implement a themed
DocContributors component at .vitepress/theme/components/DocContributors.vue
that declares a props: { showViewAll: Boolean } and renders a “View all” link
when true—choose one of these fixes and apply it so the prop is either removed
or supported.
| // 获取指定目录的所有文件 | ||
| getDirectoryFiles(dirPath) { | ||
| try { | ||
| const command = `find ${dirPath} -name "*.vue" -o -name "*.ts" -o -name "*.tsx" | head -20` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unsafe find command construction
The find command uses unescaped path which could be exploited if the path contains shell metacharacters.
- const command = `find ${dirPath} -name "*.vue" -o -name "*.ts" -o -name "*.tsx" | head -20`
+ const command = `find '${dirPath.replace(/'/g, "'\\''") }' -name "*.vue" -o -name "*.ts" -o -name "*.tsx" | head -20`📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const command = `find ${dirPath} -name "*.vue" -o -name "*.ts" -o -name "*.tsx" | head -20` | |
| const command = `find '${dirPath.replace(/'/g, "'\\''") }' -name "*.vue" -o -name "*.ts" -o -name "*.tsx" | head -20` |
|
|
||
| try { | ||
| // 使用 git log 直接分析整个目录 | ||
| const gitCommand = `git log --pretty=format:"%ae|%an|%cn" --follow -- "${componentDir.path}"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Potential command injection vulnerability
Using string concatenation for shell commands could lead to command injection if paths contain special characters. Use proper escaping or spawn with arguments array.
- const gitCommand = `git log --pretty=format:"%ae|%an|%cn" --follow -- "${componentDir.path}"`
+ // Escape the path properly
+ const escapedPath = componentDir.path.replace(/'/g, "'\\''")
+ const gitCommand = `git log --pretty=format:"%ae|%an|%cn" --follow -- '${escapedPath}'`Or better yet, use execFileSync with arguments:
const gitLogOutput = execFileSync('git', [
'log',
'--pretty=format:%ae|%an|%cn',
'--follow',
'--',
componentDir.path
], { encoding: 'utf8', cwd: process.cwd() })Also applies to: 73-73
🤖 Prompt for AI Agents
scripts/collect-contributors.js around lines 66 and 73: the code builds shell
commands with string concatenation which permits command injection when
componentDir.path contains special characters; replace the string-built git
invocation with a spawn/execFileSync call using an args array (e.g., call git
with arguments ['log', '--pretty=format:%ae|%an|%cn', '--follow', '--',
componentDir.path] and encoding:'utf8' and appropriate cwd) so the path is
passed as an argument rather than interpolated into a shell string; apply the
same change to the second occurrence on line 73.
- Refactored component paths in contributors data to include documentation and example directories. - Enhanced the script for collecting contributors to accommodate new documentation structure.
…s component - Updated the logic to find contributors for a component by matching both exact names and partial names. - Implemented a deduplication and aggregation mechanism to combine contributions from multiple components. - Sorted contributors by contribution count before returning the list.
… component - Updated the maximum contributor count displayed in the DocContributors component from 6 to 20 to enhance visibility of contributions.
效果如下

核心实现:
Git历史分析: 使用 git log 命令分析每个组件目录的提交历史
GitHub API集成: 通过GitHub API获取详细的贡献者信息(头像、用户名等)
数据聚合:
按组件目录统计贡献次数
合并相同作者的多个邮箱账号
生成组件级和文件级的贡献者统计
DocContributorscomponent to display contributors in documentation.package.jsonfor updating contributors.Summary by CodeRabbit
New Features
Documentation
Chores