repo-wrapped 0.0.2 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/generate.js +104 -95
- package/dist/constants/chronotypes.js +23 -23
- package/dist/constants/colors.js +18 -18
- package/dist/constants/index.js +18 -18
- package/dist/formatters/index.js +17 -17
- package/dist/formatters/timeFormatter.js +28 -29
- package/dist/generators/html/templates/achievementsSection.js +42 -43
- package/dist/generators/html/templates/commitQualitySection.js +25 -26
- package/dist/generators/html/templates/contributionGraph.js +47 -48
- package/dist/generators/html/templates/impactSection.js +19 -20
- package/dist/generators/html/templates/knowledgeSection.js +86 -87
- package/dist/generators/html/templates/streakSection.js +8 -9
- package/dist/generators/html/templates/timePatternsSection.js +45 -46
- package/dist/generators/html/utils/colorUtils.js +21 -21
- package/dist/generators/html/utils/commitMapBuilder.js +23 -24
- package/dist/generators/html/utils/dateRangeCalculator.js +56 -57
- package/dist/generators/html/utils/developerStatsCalculator.js +28 -29
- package/dist/generators/html/utils/scriptLoader.js +15 -16
- package/dist/generators/html/utils/styleLoader.js +17 -18
- package/dist/generators/html/utils/weekGrouper.js +27 -28
- package/dist/index.js +99 -77
- package/dist/types/index.js +2 -2
- package/dist/utils/achievementDefinitions.js +433 -433
- package/dist/utils/achievementEngine.js +169 -170
- package/dist/utils/commitQualityAnalyzer.js +367 -368
- package/dist/utils/fileHotspotAnalyzer.js +269 -270
- package/dist/utils/gitParser.js +136 -125
- package/dist/utils/htmlGenerator.js +232 -233
- package/dist/utils/impactAnalyzer.js +247 -248
- package/dist/utils/knowledgeDistributionAnalyzer.js +373 -374
- package/dist/utils/matrixGenerator.js +349 -350
- package/dist/utils/slideGenerator.js +170 -171
- package/dist/utils/streakCalculator.js +134 -135
- package/dist/utils/timePatternAnalyzer.js +304 -305
- package/dist/utils/wrappedDisplay.js +124 -115
- package/dist/utils/wrappedGenerator.js +376 -377
- package/dist/utils/wrappedHtmlGenerator.js +105 -106
- package/package.json +10 -10
|
@@ -1,35 +1,35 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.generateHTML =
|
|
4
|
-
const date_fns_1 = require("date-fns");
|
|
5
|
-
const achievementEngine_1 = require("./achievementEngine");
|
|
6
|
-
const commitQualityAnalyzer_1 = require("./commitQualityAnalyzer");
|
|
7
|
-
const fileHotspotAnalyzer_1 = require("./fileHotspotAnalyzer");
|
|
8
|
-
const impactAnalyzer_1 = require("./impactAnalyzer");
|
|
9
|
-
const knowledgeDistributionAnalyzer_1 = require("./knowledgeDistributionAnalyzer");
|
|
10
|
-
const streakCalculator_1 = require("./streakCalculator");
|
|
11
|
-
const timePatternAnalyzer_1 = require("./timePatternAnalyzer");
|
|
12
|
-
const styleLoader_1 = require("../generators/html/utils/styleLoader");
|
|
13
|
-
const scriptLoader_1 = require("../generators/html/utils/scriptLoader");
|
|
14
|
-
const contributionGraph_1 = require("../generators/html/templates/contributionGraph");
|
|
15
|
-
const streakSection_1 = require("../generators/html/templates/streakSection");
|
|
16
|
-
const timePatternsSection_1 = require("../generators/html/templates/timePatternsSection");
|
|
17
|
-
const commitQualitySection_1 = require("../generators/html/templates/commitQualitySection");
|
|
18
|
-
const achievementsSection_1 = require("../generators/html/templates/achievementsSection");
|
|
19
|
-
const impactSection_1 = require("../generators/html/templates/impactSection");
|
|
20
|
-
const knowledgeSection_1 = require("../generators/html/templates/knowledgeSection");
|
|
21
|
-
const commitMapBuilder_1 = require("../generators/html/utils/commitMapBuilder");
|
|
22
|
-
const developerStatsCalculator_1 = require("../generators/html/utils/developerStatsCalculator");
|
|
23
|
-
const dateRangeCalculator_1 = require("../generators/html/utils/dateRangeCalculator");
|
|
24
|
-
const weekGrouper_1 = require("../generators/html/utils/weekGrouper");
|
|
25
|
-
const colorUtils_1 = require("../generators/html/utils/colorUtils");
|
|
26
|
-
// Helper to format date range for display
|
|
27
|
-
function formatDateRange(start, end) {
|
|
28
|
-
return `${(0, date_fns_1.format)(start, 'MMM d, yyyy')} – ${(0, date_fns_1.format)(end, 'MMM d, yyyy')}`;
|
|
29
|
-
}
|
|
30
|
-
// Helper to build KPI header
|
|
31
|
-
function buildKPIHeader(totalCommits, qualityScore, currentStreak, activeDayPercentage) {
|
|
32
|
-
const healthScore = ((qualityScore / 10) * 0.4 + (activeDayPercentage / 100) * 0.3 + Math.min(currentStreak / 30, 1) * 0.3) * 10;
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateHTML = generateHTML;
|
|
4
|
+
const date_fns_1 = require("date-fns");
|
|
5
|
+
const achievementEngine_1 = require("./achievementEngine");
|
|
6
|
+
const commitQualityAnalyzer_1 = require("./commitQualityAnalyzer");
|
|
7
|
+
const fileHotspotAnalyzer_1 = require("./fileHotspotAnalyzer");
|
|
8
|
+
const impactAnalyzer_1 = require("./impactAnalyzer");
|
|
9
|
+
const knowledgeDistributionAnalyzer_1 = require("./knowledgeDistributionAnalyzer");
|
|
10
|
+
const streakCalculator_1 = require("./streakCalculator");
|
|
11
|
+
const timePatternAnalyzer_1 = require("./timePatternAnalyzer");
|
|
12
|
+
const styleLoader_1 = require("../generators/html/utils/styleLoader");
|
|
13
|
+
const scriptLoader_1 = require("../generators/html/utils/scriptLoader");
|
|
14
|
+
const contributionGraph_1 = require("../generators/html/templates/contributionGraph");
|
|
15
|
+
const streakSection_1 = require("../generators/html/templates/streakSection");
|
|
16
|
+
const timePatternsSection_1 = require("../generators/html/templates/timePatternsSection");
|
|
17
|
+
const commitQualitySection_1 = require("../generators/html/templates/commitQualitySection");
|
|
18
|
+
const achievementsSection_1 = require("../generators/html/templates/achievementsSection");
|
|
19
|
+
const impactSection_1 = require("../generators/html/templates/impactSection");
|
|
20
|
+
const knowledgeSection_1 = require("../generators/html/templates/knowledgeSection");
|
|
21
|
+
const commitMapBuilder_1 = require("../generators/html/utils/commitMapBuilder");
|
|
22
|
+
const developerStatsCalculator_1 = require("../generators/html/utils/developerStatsCalculator");
|
|
23
|
+
const dateRangeCalculator_1 = require("../generators/html/utils/dateRangeCalculator");
|
|
24
|
+
const weekGrouper_1 = require("../generators/html/utils/weekGrouper");
|
|
25
|
+
const colorUtils_1 = require("../generators/html/utils/colorUtils");
|
|
26
|
+
// Helper to format date range for display
|
|
27
|
+
function formatDateRange(start, end) {
|
|
28
|
+
return `${(0, date_fns_1.format)(start, 'MMM d, yyyy')} – ${(0, date_fns_1.format)(end, 'MMM d, yyyy')}`;
|
|
29
|
+
}
|
|
30
|
+
// Helper to build KPI header
|
|
31
|
+
function buildKPIHeader(totalCommits, qualityScore, currentStreak, activeDayPercentage) {
|
|
32
|
+
const healthScore = ((qualityScore / 10) * 0.4 + (activeDayPercentage / 100) * 0.3 + Math.min(currentStreak / 30, 1) * 0.3) * 10;
|
|
33
33
|
return `
|
|
34
34
|
<header class="kpi-header">
|
|
35
35
|
<div class="kpi-card">
|
|
@@ -53,10 +53,10 @@ function buildKPIHeader(totalCommits, qualityScore, currentStreak, activeDayPerc
|
|
|
53
53
|
<span class="kpi-value">${activeDayPercentage.toFixed(0)}%</span>
|
|
54
54
|
</div>
|
|
55
55
|
</header>
|
|
56
|
-
`;
|
|
57
|
-
}
|
|
58
|
-
// Helper to wrap content in collapsible section
|
|
59
|
-
function wrapInSection(id, title, content, icon = '') {
|
|
56
|
+
`;
|
|
57
|
+
}
|
|
58
|
+
// Helper to wrap content in collapsible section
|
|
59
|
+
function wrapInSection(id, title, content, icon = '') {
|
|
60
60
|
return `
|
|
61
61
|
<section class="dashboard-section" id="${id}">
|
|
62
62
|
<header class="section-header" role="button" aria-expanded="true">
|
|
@@ -67,85 +67,84 @@ function wrapInSection(id, title, content, icon = '') {
|
|
|
67
67
|
${content}
|
|
68
68
|
</div>
|
|
69
69
|
</section>
|
|
70
|
-
`;
|
|
71
|
-
}
|
|
72
|
-
function generateHTML(commits, year, monthsToShow, repoPath, repoName, repoUrl, skipBodyCheck = false, allTime = false, deepAnalysis = false) {
|
|
73
|
-
// Get current git user
|
|
74
|
-
const { getCurrentGitUser } = require('./gitParser');
|
|
75
|
-
const currentUser = getCurrentGitUser(repoPath);
|
|
76
|
-
// Calculate date ranges
|
|
77
|
-
const { startDate, endDate, weekStartDate, weekEndDate } = allTime
|
|
78
|
-
? (0, dateRangeCalculator_1.calculateDateRangesFromCommits)(commits)
|
|
79
|
-
: (0, dateRangeCalculator_1.calculateDateRanges)(year, monthsToShow);
|
|
80
|
-
// Create commit maps for overall and personal commits
|
|
81
|
-
const { commitMap, commitDetailsMap } = (0, commitMapBuilder_1.createCommitMaps)(commits, startDate, endDate);
|
|
82
|
-
const personalCommits = commits.filter(c => c.author === currentUser);
|
|
83
|
-
const { commitMap: personalCommitMap, commitDetailsMap: personalCommitDetailsMap } = (0, commitMapBuilder_1.createCommitMaps)(personalCommits, startDate, endDate);
|
|
84
|
-
// Calculate per-developer statistics
|
|
85
|
-
const developerStats = (0, developerStatsCalculator_1.calculateDeveloperStats)(commits, startDate, endDate);
|
|
86
|
-
// Calculate streak data (overall and personal)
|
|
87
|
-
const streakData = (0, streakCalculator_1.calculateStreaks)(commits, startDate, endDate);
|
|
88
|
-
const personalStreakData = (0, streakCalculator_1.calculateStreaks)(personalCommits, startDate, endDate);
|
|
89
|
-
// Analyze time patterns (overall and personal)
|
|
90
|
-
const timePattern = (0, timePatternAnalyzer_1.analyzeTimePatterns)(commits, startDate, endDate);
|
|
91
|
-
const personalTimePattern = (0, timePatternAnalyzer_1.analyzeTimePatterns)(personalCommits, startDate, endDate);
|
|
92
|
-
// Analyze commit quality (overall and personal)
|
|
93
|
-
const commitQuality = (0, commitQualityAnalyzer_1.analyzeCommitQuality)(commits, { skipBodyCheck });
|
|
94
|
-
const personalCommitQuality = (0, commitQualityAnalyzer_1.analyzeCommitQuality)(personalCommits, { skipBodyCheck });
|
|
95
|
-
// Analyze file hotspots
|
|
96
|
-
const fileHotspots = (0, fileHotspotAnalyzer_1.analyzeFileHotspots)(repoPath, startDate, endDate);
|
|
97
|
-
// Analyze impact and knowledge distribution (enterprise insights)
|
|
98
|
-
const impactAnalysis = (0, impactAnalyzer_1.analyzeImpact)(commits);
|
|
99
|
-
const knowledgeDistribution = (0, knowledgeDistributionAnalyzer_1.analyzeKnowledgeDistribution)(commits, repoPath, deepAnalysis);
|
|
100
|
-
const totalCommits = Array.from(commitMap.values()).reduce((sum, count) => sum + count, 0);
|
|
101
|
-
const totalPersonalCommits = Array.from(personalCommitMap.values()).reduce((sum, count) => sum + count, 0);
|
|
102
|
-
// Prepare analysis data for achievements (overall and personal)
|
|
103
|
-
const analysisData = {
|
|
104
|
-
commits,
|
|
105
|
-
totalCommits,
|
|
106
|
-
streakData,
|
|
107
|
-
timePattern,
|
|
108
|
-
commitQuality,
|
|
109
|
-
fileHotspots,
|
|
110
|
-
dateRange: { start: startDate, end: endDate }
|
|
111
|
-
};
|
|
112
|
-
const personalAnalysisData = {
|
|
113
|
-
commits: personalCommits,
|
|
114
|
-
totalCommits: totalPersonalCommits,
|
|
115
|
-
streakData: personalStreakData,
|
|
116
|
-
timePattern: personalTimePattern,
|
|
117
|
-
commitQuality: personalCommitQuality,
|
|
118
|
-
fileHotspots,
|
|
119
|
-
dateRange: { start: startDate, end: endDate }
|
|
120
|
-
};
|
|
121
|
-
// Check achievements
|
|
122
|
-
const achievementProgress = (0, achievementEngine_1.checkAchievements)(analysisData);
|
|
123
|
-
const personalAchievementProgress = (0, achievementEngine_1.checkAchievements)(personalAnalysisData);
|
|
124
|
-
return generateHTMLContent(commitMap, commitDetailsMap, developerStats, streakData, timePattern, commitQuality, fileHotspots, achievementProgress, personalCommitMap, personalCommitDetailsMap, personalStreakData, personalTimePattern, personalCommitQuality, personalAchievementProgress, weekStartDate, weekEndDate, startDate, endDate, repoName, repoUrl, currentUser, skipBodyCheck, impactAnalysis, knowledgeDistribution);
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
const
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
const
|
|
145
|
-
const
|
|
146
|
-
const
|
|
147
|
-
|
|
148
|
-
// Combine all sections with collapsible wrappers
|
|
70
|
+
`;
|
|
71
|
+
}
|
|
72
|
+
function generateHTML(commits, year, monthsToShow, repoPath, repoName, repoUrl, skipBodyCheck = false, allTime = false, deepAnalysis = false) {
|
|
73
|
+
// Get current git user
|
|
74
|
+
const { getCurrentGitUser } = require('./gitParser');
|
|
75
|
+
const currentUser = getCurrentGitUser(repoPath);
|
|
76
|
+
// Calculate date ranges
|
|
77
|
+
const { startDate, endDate, weekStartDate, weekEndDate } = allTime
|
|
78
|
+
? (0, dateRangeCalculator_1.calculateDateRangesFromCommits)(commits)
|
|
79
|
+
: (0, dateRangeCalculator_1.calculateDateRanges)(year, monthsToShow);
|
|
80
|
+
// Create commit maps for overall and personal commits
|
|
81
|
+
const { commitMap, commitDetailsMap } = (0, commitMapBuilder_1.createCommitMaps)(commits, startDate, endDate);
|
|
82
|
+
const personalCommits = commits.filter(c => c.author === currentUser);
|
|
83
|
+
const { commitMap: personalCommitMap, commitDetailsMap: personalCommitDetailsMap } = (0, commitMapBuilder_1.createCommitMaps)(personalCommits, startDate, endDate);
|
|
84
|
+
// Calculate per-developer statistics
|
|
85
|
+
const developerStats = (0, developerStatsCalculator_1.calculateDeveloperStats)(commits, startDate, endDate);
|
|
86
|
+
// Calculate streak data (overall and personal)
|
|
87
|
+
const streakData = (0, streakCalculator_1.calculateStreaks)(commits, startDate, endDate);
|
|
88
|
+
const personalStreakData = (0, streakCalculator_1.calculateStreaks)(personalCommits, startDate, endDate);
|
|
89
|
+
// Analyze time patterns (overall and personal)
|
|
90
|
+
const timePattern = (0, timePatternAnalyzer_1.analyzeTimePatterns)(commits, startDate, endDate);
|
|
91
|
+
const personalTimePattern = (0, timePatternAnalyzer_1.analyzeTimePatterns)(personalCommits, startDate, endDate);
|
|
92
|
+
// Analyze commit quality (overall and personal)
|
|
93
|
+
const commitQuality = (0, commitQualityAnalyzer_1.analyzeCommitQuality)(commits, { skipBodyCheck });
|
|
94
|
+
const personalCommitQuality = (0, commitQualityAnalyzer_1.analyzeCommitQuality)(personalCommits, { skipBodyCheck });
|
|
95
|
+
// Analyze file hotspots
|
|
96
|
+
const fileHotspots = (0, fileHotspotAnalyzer_1.analyzeFileHotspots)(repoPath, startDate, endDate);
|
|
97
|
+
// Analyze impact and knowledge distribution (enterprise insights)
|
|
98
|
+
const impactAnalysis = (0, impactAnalyzer_1.analyzeImpact)(commits);
|
|
99
|
+
const knowledgeDistribution = (0, knowledgeDistributionAnalyzer_1.analyzeKnowledgeDistribution)(commits, repoPath, deepAnalysis);
|
|
100
|
+
const totalCommits = Array.from(commitMap.values()).reduce((sum, count) => sum + count, 0);
|
|
101
|
+
const totalPersonalCommits = Array.from(personalCommitMap.values()).reduce((sum, count) => sum + count, 0);
|
|
102
|
+
// Prepare analysis data for achievements (overall and personal)
|
|
103
|
+
const analysisData = {
|
|
104
|
+
commits,
|
|
105
|
+
totalCommits,
|
|
106
|
+
streakData,
|
|
107
|
+
timePattern,
|
|
108
|
+
commitQuality,
|
|
109
|
+
fileHotspots,
|
|
110
|
+
dateRange: { start: startDate, end: endDate }
|
|
111
|
+
};
|
|
112
|
+
const personalAnalysisData = {
|
|
113
|
+
commits: personalCommits,
|
|
114
|
+
totalCommits: totalPersonalCommits,
|
|
115
|
+
streakData: personalStreakData,
|
|
116
|
+
timePattern: personalTimePattern,
|
|
117
|
+
commitQuality: personalCommitQuality,
|
|
118
|
+
fileHotspots,
|
|
119
|
+
dateRange: { start: startDate, end: endDate }
|
|
120
|
+
};
|
|
121
|
+
// Check achievements
|
|
122
|
+
const achievementProgress = (0, achievementEngine_1.checkAchievements)(analysisData);
|
|
123
|
+
const personalAchievementProgress = (0, achievementEngine_1.checkAchievements)(personalAnalysisData);
|
|
124
|
+
return generateHTMLContent(commitMap, commitDetailsMap, developerStats, streakData, timePattern, commitQuality, fileHotspots, achievementProgress, personalCommitMap, personalCommitDetailsMap, personalStreakData, personalTimePattern, personalCommitQuality, personalAchievementProgress, weekStartDate, weekEndDate, startDate, endDate, repoName, repoUrl, currentUser, skipBodyCheck, impactAnalysis, knowledgeDistribution);
|
|
125
|
+
}
|
|
126
|
+
function generatePersonalContent(personalCommitMap, personalCommitDetailsMap, streakData, timePattern, commitQuality, achievementProgress, weekStartDate, weekEndDate, dataStartDate, dataEndDate, currentUser, totalCommits, skipBodyCheck = false) {
|
|
127
|
+
const weeks = (0, weekGrouper_1.groupDaysIntoWeeks)(weekStartDate, weekEndDate);
|
|
128
|
+
const dayLabels = (0, weekGrouper_1.getDayLabels)();
|
|
129
|
+
// Build KPI header for personal stats
|
|
130
|
+
const kpiHeader = buildKPIHeader(totalCommits, commitQuality.overallScore, streakData.currentStreak.days, streakData.activeDayPercentage);
|
|
131
|
+
// Generate sections using template builders
|
|
132
|
+
const contributionGraphHtml = (0, contributionGraph_1.buildContributionGraph)({
|
|
133
|
+
commitMap: personalCommitMap,
|
|
134
|
+
commitDetailsMap: personalCommitDetailsMap,
|
|
135
|
+
weeks,
|
|
136
|
+
dayLabels,
|
|
137
|
+
dataStartDate,
|
|
138
|
+
dataEndDate,
|
|
139
|
+
totalCommits,
|
|
140
|
+
title: 'Your contributions',
|
|
141
|
+
getColorFn: colorUtils_1.getColor
|
|
142
|
+
});
|
|
143
|
+
const streakSectionHtml = (0, streakSection_1.buildStreakSection)(streakData);
|
|
144
|
+
const timePatternsHtml = (0, timePatternsSection_1.buildTimePatternsSection)(timePattern);
|
|
145
|
+
const commitQualityHtml = (0, commitQualitySection_1.buildCommitQualitySection)(commitQuality, totalCommits, skipBodyCheck);
|
|
146
|
+
const achievementsHtml = (0, achievementsSection_1.buildAchievementsSection)(achievementProgress);
|
|
147
|
+
// Combine all sections with collapsible wrappers
|
|
149
148
|
return `
|
|
150
149
|
${kpiHeader}
|
|
151
150
|
|
|
@@ -154,75 +153,75 @@ function generatePersonalContent(personalCommitMap, personalCommitDetailsMap, st
|
|
|
154
153
|
${wrapInSection('personal-patterns', 'Time Patterns', timePatternsHtml)}
|
|
155
154
|
${wrapInSection('personal-quality', 'Commit Quality', commitQualityHtml)}
|
|
156
155
|
${wrapInSection('personal-achievements', 'Achievements', achievementsHtml)}
|
|
157
|
-
`;
|
|
158
|
-
}
|
|
159
|
-
function generateHTMLContent(commitMap, commitDetailsMap, developerStats, streakData, timePattern, commitQuality, fileHotspots, achievementProgress, personalCommitMap, personalCommitDetailsMap, personalStreakData, personalTimePattern, personalCommitQuality, personalAchievementProgress, weekStartDate, weekEndDate, dataStartDate, dataEndDate, repoName, repoUrl, currentUser, skipBodyCheck = false, impactAnalysis, knowledgeDistribution) {
|
|
160
|
-
const totalPersonalCommits = Array.from(personalCommitMap.values()).reduce((sum, count) => sum + count, 0);
|
|
161
|
-
const weeks = (0, weekGrouper_1.groupDaysIntoWeeks)(weekStartDate, weekEndDate);
|
|
162
|
-
// Build month labels and track month boundaries
|
|
163
|
-
let monthLabels = '';
|
|
164
|
-
let currentMonth = '';
|
|
165
|
-
const monthBoundaries = new Set();
|
|
166
|
-
weeks.forEach((week, weekIndex) => {
|
|
167
|
-
const firstDayOfWeek = week[0];
|
|
168
|
-
const monthName = (0, date_fns_1.format)(firstDayOfWeek, 'MMM');
|
|
169
|
-
if (monthName !== currentMonth) {
|
|
170
|
-
currentMonth = monthName;
|
|
171
|
-
if (weekIndex > 0) {
|
|
172
|
-
monthBoundaries.add(weekIndex);
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
});
|
|
176
|
-
// Build week columns
|
|
177
|
-
let weekColumns = '';
|
|
178
|
-
const dayLabels = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
|
|
179
|
-
weeks.forEach((week, weekIndex) => {
|
|
180
|
-
let weekColumn = `<div class="graph-column">`;
|
|
181
|
-
week.forEach((day, dayOfWeek) => {
|
|
182
|
-
const dateKey = (0, date_fns_1.format)(day, 'yyyy-MM-dd');
|
|
183
|
-
const count = commitMap.get(dateKey) || 0;
|
|
184
|
-
const isInRange = day >= dataStartDate && day <= dataEndDate;
|
|
185
|
-
const color = isInRange ? (0, colorUtils_1.getColor)(count) : 'transparent';
|
|
186
|
-
const dateStr = (0, date_fns_1.format)(day, 'MMM d, yyyy');
|
|
187
|
-
const emptyClass = count === 0 ? ' empty' : '';
|
|
188
|
-
const clickable = count > 0 ? ' clickable' : '';
|
|
189
|
-
const detailsData = count > 0 ? `data-details='${JSON.stringify(commitDetailsMap.get(dateKey) || [])}'` : '';
|
|
190
|
-
weekColumn += `<div class="day${emptyClass}${clickable}" style="background-color: ${color};" data-count="${count}" data-date="${dateStr}" ${detailsData}></div>`;
|
|
191
|
-
});
|
|
192
|
-
weekColumn += '</div>';
|
|
193
|
-
weekColumns += weekColumn;
|
|
194
|
-
});
|
|
195
|
-
// Build day labels column
|
|
196
|
-
let dayLabelsHtml = '<div class="day-labels">';
|
|
197
|
-
dayLabels.forEach((label, index) => {
|
|
198
|
-
const displayLabel = [1, 3, 5].includes(index) ? label : '';
|
|
199
|
-
dayLabelsHtml += `<div class="day-label">${displayLabel}</div>`;
|
|
200
|
-
});
|
|
201
|
-
dayLabelsHtml += '</div>';
|
|
202
|
-
// Build month labels header
|
|
203
|
-
let monthLabelsHtml = '';
|
|
204
|
-
currentMonth = '';
|
|
205
|
-
weeks.forEach((week, weekIndex) => {
|
|
206
|
-
const firstDayOfWeek = week[0];
|
|
207
|
-
const monthName = (0, date_fns_1.format)(firstDayOfWeek, 'MMM');
|
|
208
|
-
if (monthName !== currentMonth) {
|
|
209
|
-
monthLabelsHtml += `<div class="month-label">${monthName}</div>`;
|
|
210
|
-
currentMonth = monthName;
|
|
211
|
-
}
|
|
212
|
-
else {
|
|
213
|
-
monthLabelsHtml += `<div class="month-label"></div>`;
|
|
214
|
-
}
|
|
215
|
-
});
|
|
216
|
-
const totalCommits = Array.from(commitMap.values()).reduce((sum, count) => sum + count, 0);
|
|
217
|
-
// Sort developers by commit count
|
|
218
|
-
const sortedDevelopers = Array.from(developerStats.entries())
|
|
219
|
-
.sort((a, b) => b[1].commits - a[1].commits);
|
|
220
|
-
// Generate developer analysis HTML
|
|
221
|
-
const developerAnalysisHtml = sortedDevelopers.map(([author, stats]) => {
|
|
222
|
-
const percentage = ((stats.commits / totalCommits) * 100).toFixed(1);
|
|
223
|
-
const dateRange = stats.firstCommit.toDateString() === stats.lastCommit.toDateString()
|
|
224
|
-
? (0, date_fns_1.format)(stats.firstCommit, 'MMM d, yyyy')
|
|
225
|
-
: `${(0, date_fns_1.format)(stats.firstCommit, 'MMM d, yyyy')} - ${(0, date_fns_1.format)(stats.lastCommit, 'MMM d, yyyy')}`;
|
|
156
|
+
`;
|
|
157
|
+
}
|
|
158
|
+
function generateHTMLContent(commitMap, commitDetailsMap, developerStats, streakData, timePattern, commitQuality, fileHotspots, achievementProgress, personalCommitMap, personalCommitDetailsMap, personalStreakData, personalTimePattern, personalCommitQuality, personalAchievementProgress, weekStartDate, weekEndDate, dataStartDate, dataEndDate, repoName, repoUrl, currentUser, skipBodyCheck = false, impactAnalysis, knowledgeDistribution) {
|
|
159
|
+
const totalPersonalCommits = Array.from(personalCommitMap.values()).reduce((sum, count) => sum + count, 0);
|
|
160
|
+
const weeks = (0, weekGrouper_1.groupDaysIntoWeeks)(weekStartDate, weekEndDate);
|
|
161
|
+
// Build month labels and track month boundaries
|
|
162
|
+
let monthLabels = '';
|
|
163
|
+
let currentMonth = '';
|
|
164
|
+
const monthBoundaries = new Set();
|
|
165
|
+
weeks.forEach((week, weekIndex) => {
|
|
166
|
+
const firstDayOfWeek = week[0];
|
|
167
|
+
const monthName = (0, date_fns_1.format)(firstDayOfWeek, 'MMM');
|
|
168
|
+
if (monthName !== currentMonth) {
|
|
169
|
+
currentMonth = monthName;
|
|
170
|
+
if (weekIndex > 0) {
|
|
171
|
+
monthBoundaries.add(weekIndex);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
// Build week columns
|
|
176
|
+
let weekColumns = '';
|
|
177
|
+
const dayLabels = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
|
|
178
|
+
weeks.forEach((week, weekIndex) => {
|
|
179
|
+
let weekColumn = `<div class="graph-column">`;
|
|
180
|
+
week.forEach((day, dayOfWeek) => {
|
|
181
|
+
const dateKey = (0, date_fns_1.format)(day, 'yyyy-MM-dd');
|
|
182
|
+
const count = commitMap.get(dateKey) || 0;
|
|
183
|
+
const isInRange = day >= dataStartDate && day <= dataEndDate;
|
|
184
|
+
const color = isInRange ? (0, colorUtils_1.getColor)(count) : 'transparent';
|
|
185
|
+
const dateStr = (0, date_fns_1.format)(day, 'MMM d, yyyy');
|
|
186
|
+
const emptyClass = count === 0 ? ' empty' : '';
|
|
187
|
+
const clickable = count > 0 ? ' clickable' : '';
|
|
188
|
+
const detailsData = count > 0 ? `data-details='${JSON.stringify(commitDetailsMap.get(dateKey) || [])}'` : '';
|
|
189
|
+
weekColumn += `<div class="day${emptyClass}${clickable}" style="background-color: ${color};" data-count="${count}" data-date="${dateStr}" ${detailsData}></div>`;
|
|
190
|
+
});
|
|
191
|
+
weekColumn += '</div>';
|
|
192
|
+
weekColumns += weekColumn;
|
|
193
|
+
});
|
|
194
|
+
// Build day labels column
|
|
195
|
+
let dayLabelsHtml = '<div class="day-labels">';
|
|
196
|
+
dayLabels.forEach((label, index) => {
|
|
197
|
+
const displayLabel = [1, 3, 5].includes(index) ? label : '';
|
|
198
|
+
dayLabelsHtml += `<div class="day-label">${displayLabel}</div>`;
|
|
199
|
+
});
|
|
200
|
+
dayLabelsHtml += '</div>';
|
|
201
|
+
// Build month labels header
|
|
202
|
+
let monthLabelsHtml = '';
|
|
203
|
+
currentMonth = '';
|
|
204
|
+
weeks.forEach((week, weekIndex) => {
|
|
205
|
+
const firstDayOfWeek = week[0];
|
|
206
|
+
const monthName = (0, date_fns_1.format)(firstDayOfWeek, 'MMM');
|
|
207
|
+
if (monthName !== currentMonth) {
|
|
208
|
+
monthLabelsHtml += `<div class="month-label">${monthName}</div>`;
|
|
209
|
+
currentMonth = monthName;
|
|
210
|
+
}
|
|
211
|
+
else {
|
|
212
|
+
monthLabelsHtml += `<div class="month-label"></div>`;
|
|
213
|
+
}
|
|
214
|
+
});
|
|
215
|
+
const totalCommits = Array.from(commitMap.values()).reduce((sum, count) => sum + count, 0);
|
|
216
|
+
// Sort developers by commit count
|
|
217
|
+
const sortedDevelopers = Array.from(developerStats.entries())
|
|
218
|
+
.sort((a, b) => b[1].commits - a[1].commits);
|
|
219
|
+
// Generate developer analysis HTML
|
|
220
|
+
const developerAnalysisHtml = sortedDevelopers.map(([author, stats]) => {
|
|
221
|
+
const percentage = ((stats.commits / totalCommits) * 100).toFixed(1);
|
|
222
|
+
const dateRange = stats.firstCommit.toDateString() === stats.lastCommit.toDateString()
|
|
223
|
+
? (0, date_fns_1.format)(stats.firstCommit, 'MMM d, yyyy')
|
|
224
|
+
: `${(0, date_fns_1.format)(stats.firstCommit, 'MMM d, yyyy')} - ${(0, date_fns_1.format)(stats.lastCommit, 'MMM d, yyyy')}`;
|
|
226
225
|
return `
|
|
227
226
|
<div class="developer-row">
|
|
228
227
|
<div class="developer-info">
|
|
@@ -236,9 +235,9 @@ function generateHTMLContent(commitMap, commitDetailsMap, developerStats, streak
|
|
|
236
235
|
<div class="developer-count">${stats.commits} commits (${percentage}%)</div>
|
|
237
236
|
</div>
|
|
238
237
|
</div>
|
|
239
|
-
`;
|
|
240
|
-
}).join('');
|
|
241
|
-
// Build contribution graph HTML for Overall tab
|
|
238
|
+
`;
|
|
239
|
+
}).join('');
|
|
240
|
+
// Build contribution graph HTML for Overall tab
|
|
242
241
|
const contributionGraphHtml = `
|
|
243
242
|
<div class="graph-container">
|
|
244
243
|
<div class="months">
|
|
@@ -260,14 +259,14 @@ function generateHTMLContent(commitMap, commitDetailsMap, developerStats, streak
|
|
|
260
259
|
<span>More</span>
|
|
261
260
|
</div>
|
|
262
261
|
</div>
|
|
263
|
-
`;
|
|
262
|
+
`;
|
|
264
263
|
const developerSectionHtml = `
|
|
265
264
|
<div class="developer-analysis">
|
|
266
265
|
${developerAnalysisHtml}
|
|
267
266
|
</div>
|
|
268
|
-
`;
|
|
269
|
-
// Build KPI header for Overall tab
|
|
270
|
-
const overallKpiHeader = buildKPIHeader(totalCommits, commitQuality.overallScore, streakData.currentStreak.days, streakData.activeDayPercentage);
|
|
267
|
+
`;
|
|
268
|
+
// Build KPI header for Overall tab
|
|
269
|
+
const overallKpiHeader = buildKPIHeader(totalCommits, commitQuality.overallScore, streakData.currentStreak.days, streakData.activeDayPercentage);
|
|
271
270
|
return `<!DOCTYPE html>
|
|
272
271
|
<html lang="en">
|
|
273
272
|
<head>
|
|
@@ -398,46 +397,46 @@ function generateHTMLContent(commitMap, commitDetailsMap, developerStats, streak
|
|
|
398
397
|
|
|
399
398
|
<script>
|
|
400
399
|
// Embed data for export functionality
|
|
401
|
-
window.__GITWRAPPED_DATA__ = ${JSON.stringify({
|
|
402
|
-
repository: repoName,
|
|
403
|
-
period: {
|
|
404
|
-
start: dataStartDate.toISOString(),
|
|
405
|
-
end: dataEndDate.toISOString()
|
|
406
|
-
},
|
|
407
|
-
author: currentUser,
|
|
408
|
-
summary: {
|
|
409
|
-
totalCommits: totalCommits,
|
|
410
|
-
totalContributors: developerStats.size,
|
|
411
|
-
activeDays: commitMap.size
|
|
412
|
-
},
|
|
413
|
-
streaks: {
|
|
414
|
-
currentStreak: streakData.currentStreak.days,
|
|
415
|
-
longestStreak: streakData.longestStreak.days,
|
|
416
|
-
totalActiveDays: streakData.totalActiveDays,
|
|
417
|
-
activeDayPercentage: streakData.activeDayPercentage
|
|
418
|
-
},
|
|
419
|
-
quality: {
|
|
420
|
-
overallScore: commitQuality.overallScore,
|
|
421
|
-
conventionalAdherence: commitQuality.conventionalCommits.adherence,
|
|
422
|
-
avgSubjectLength: commitQuality.subjectQuality.avgLength
|
|
423
|
-
},
|
|
424
|
-
timePattern: {
|
|
425
|
-
chronotype: timePattern.chronotype,
|
|
426
|
-
peakHour: timePattern.peakHour.hour,
|
|
427
|
-
consistency: timePattern.consistency?.score || 0
|
|
428
|
-
},
|
|
429
|
-
commits: Array.from(commitDetailsMap.values()).flat().map((c) => ({
|
|
430
|
-
date: c.date,
|
|
431
|
-
author: c.author,
|
|
432
|
-
message: c.message.split('\\n')[0],
|
|
433
|
-
hash: c.hash
|
|
434
|
-
})),
|
|
435
|
-
developerStats: Array.from(developerStats.entries()).map(([name, stats]) => ({
|
|
436
|
-
name,
|
|
437
|
-
commits: stats.commits,
|
|
438
|
-
firstCommit: stats.firstCommit.toISOString(),
|
|
439
|
-
lastCommit: stats.lastCommit.toISOString()
|
|
440
|
-
}))
|
|
400
|
+
window.__GITWRAPPED_DATA__ = ${JSON.stringify({
|
|
401
|
+
repository: repoName,
|
|
402
|
+
period: {
|
|
403
|
+
start: dataStartDate.toISOString(),
|
|
404
|
+
end: dataEndDate.toISOString()
|
|
405
|
+
},
|
|
406
|
+
author: currentUser,
|
|
407
|
+
summary: {
|
|
408
|
+
totalCommits: totalCommits,
|
|
409
|
+
totalContributors: developerStats.size,
|
|
410
|
+
activeDays: commitMap.size
|
|
411
|
+
},
|
|
412
|
+
streaks: {
|
|
413
|
+
currentStreak: streakData.currentStreak.days,
|
|
414
|
+
longestStreak: streakData.longestStreak.days,
|
|
415
|
+
totalActiveDays: streakData.totalActiveDays,
|
|
416
|
+
activeDayPercentage: streakData.activeDayPercentage
|
|
417
|
+
},
|
|
418
|
+
quality: {
|
|
419
|
+
overallScore: commitQuality.overallScore,
|
|
420
|
+
conventionalAdherence: commitQuality.conventionalCommits.adherence,
|
|
421
|
+
avgSubjectLength: commitQuality.subjectQuality.avgLength
|
|
422
|
+
},
|
|
423
|
+
timePattern: {
|
|
424
|
+
chronotype: timePattern.chronotype,
|
|
425
|
+
peakHour: timePattern.peakHour.hour,
|
|
426
|
+
consistency: timePattern.consistency?.score || 0
|
|
427
|
+
},
|
|
428
|
+
commits: Array.from(commitDetailsMap.values()).flat().map((c) => ({
|
|
429
|
+
date: c.date,
|
|
430
|
+
author: c.author,
|
|
431
|
+
message: c.message.split('\\n')[0],
|
|
432
|
+
hash: c.hash
|
|
433
|
+
})),
|
|
434
|
+
developerStats: Array.from(developerStats.entries()).map(([name, stats]) => ({
|
|
435
|
+
name,
|
|
436
|
+
commits: stats.commits,
|
|
437
|
+
firstCommit: stats.firstCommit.toISOString(),
|
|
438
|
+
lastCommit: stats.lastCommit.toISOString()
|
|
439
|
+
}))
|
|
441
440
|
})};
|
|
442
441
|
</script>
|
|
443
442
|
|
|
@@ -445,5 +444,5 @@ function generateHTMLContent(commitMap, commitDetailsMap, developerStats, streak
|
|
|
445
444
|
${(0, scriptLoader_1.loadScripts)()}
|
|
446
445
|
</script>
|
|
447
446
|
</body>
|
|
448
|
-
</html>`;
|
|
449
|
-
}
|
|
447
|
+
</html>`;
|
|
448
|
+
}
|