repo-wrapped 0.0.3 → 0.0.5
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 +64 -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 +61 -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 +78 -78
- 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 -126
- package/dist/utils/htmlGenerator.js +245 -233
- package/dist/utils/impactAnalyzer.js +247 -248
- package/dist/utils/knowledgeDistributionAnalyzer.js +380 -374
- package/dist/utils/matrixGenerator.js +369 -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,170 +1,169 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
//
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
metaAch
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
metaAch
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
metaAch.progress = Math.min(100, (unlockedCount /
|
|
56
|
-
}
|
|
57
|
-
else if (metaAch.id === '
|
|
58
|
-
metaAch.progress = Math.min(100, (unlockedCount /
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
case '
|
|
125
|
-
return data.
|
|
126
|
-
case '
|
|
127
|
-
return data.
|
|
128
|
-
|
|
129
|
-
return
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
case '
|
|
137
|
-
return value
|
|
138
|
-
case '
|
|
139
|
-
return value
|
|
140
|
-
case '
|
|
141
|
-
return value
|
|
142
|
-
case '
|
|
143
|
-
return value
|
|
144
|
-
|
|
145
|
-
return
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
function getNextMilestone(progress) {
|
|
165
|
-
const locked = progress.achievements.filter(a => !a.isUnlocked);
|
|
166
|
-
if (locked.length === 0)
|
|
167
|
-
return null;
|
|
168
|
-
return locked.reduce((closest, current) => current.progress > closest.progress ? current : closest);
|
|
169
|
-
}
|
|
170
|
-
exports.getNextMilestone = getNextMilestone;
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.checkAchievements = checkAchievements;
|
|
4
|
+
exports.getRecentAchievements = getRecentAchievements;
|
|
5
|
+
exports.getAchievementsByCategory = getAchievementsByCategory;
|
|
6
|
+
exports.getNextMilestone = getNextMilestone;
|
|
7
|
+
const achievementDefinitions_1 = require("./achievementDefinitions");
|
|
8
|
+
function checkAchievements(data) {
|
|
9
|
+
// Create a deep copy of achievements to avoid mutation
|
|
10
|
+
const achievements = achievementDefinitions_1.ACHIEVEMENTS.map(a => ({ ...a }));
|
|
11
|
+
const newlyEarned = [];
|
|
12
|
+
// Check each achievement
|
|
13
|
+
for (const achievement of achievements) {
|
|
14
|
+
if (!achievement.isUnlocked) {
|
|
15
|
+
// Calculate progress
|
|
16
|
+
achievement.progress = calculateProgress(achievement, data);
|
|
17
|
+
// Check if criteria is met
|
|
18
|
+
if (meetsCriteria(achievement, data)) {
|
|
19
|
+
achievement.isUnlocked = true;
|
|
20
|
+
achievement.earnedDate = new Date();
|
|
21
|
+
newlyEarned.push(achievement);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
// Already unlocked, progress is 100
|
|
26
|
+
achievement.progress = 100;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
// Check meta achievements (based on unlocked count)
|
|
30
|
+
const unlockedCount = achievements.filter(a => a.isUnlocked && a.category !== 'meta').length;
|
|
31
|
+
const metaAchievements = achievements.filter(a => a.category === 'meta');
|
|
32
|
+
for (const metaAch of metaAchievements) {
|
|
33
|
+
if (!metaAch.isUnlocked) {
|
|
34
|
+
if (metaAch.id === 'collector' && unlockedCount >= 10) {
|
|
35
|
+
metaAch.isUnlocked = true;
|
|
36
|
+
metaAch.earnedDate = new Date();
|
|
37
|
+
metaAch.progress = 100;
|
|
38
|
+
newlyEarned.push(metaAch);
|
|
39
|
+
}
|
|
40
|
+
else if (metaAch.id === 'completionist' && unlockedCount >= 25) {
|
|
41
|
+
metaAch.isUnlocked = true;
|
|
42
|
+
metaAch.earnedDate = new Date();
|
|
43
|
+
metaAch.progress = 100;
|
|
44
|
+
newlyEarned.push(metaAch);
|
|
45
|
+
}
|
|
46
|
+
else if (metaAch.id === 'badge-king' && unlockedCount >= 50) {
|
|
47
|
+
metaAch.isUnlocked = true;
|
|
48
|
+
metaAch.earnedDate = new Date();
|
|
49
|
+
metaAch.progress = 100;
|
|
50
|
+
newlyEarned.push(metaAch);
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
// Calculate meta progress
|
|
54
|
+
if (metaAch.id === 'collector') {
|
|
55
|
+
metaAch.progress = Math.min(100, (unlockedCount / 10) * 100);
|
|
56
|
+
}
|
|
57
|
+
else if (metaAch.id === 'completionist') {
|
|
58
|
+
metaAch.progress = Math.min(100, (unlockedCount / 25) * 100);
|
|
59
|
+
}
|
|
60
|
+
else if (metaAch.id === 'badge-king') {
|
|
61
|
+
metaAch.progress = Math.min(100, (unlockedCount / 50) * 100);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
// Find next milestones (top 3 closest to unlocking)
|
|
67
|
+
const lockedAchievements = achievements.filter(a => !a.isUnlocked);
|
|
68
|
+
const nextMilestones = lockedAchievements
|
|
69
|
+
.sort((a, b) => b.progress - a.progress)
|
|
70
|
+
.slice(0, 3);
|
|
71
|
+
const totalUnlocked = achievements.filter(a => a.isUnlocked).length;
|
|
72
|
+
const completionPercentage = (totalUnlocked / achievements.length) * 100;
|
|
73
|
+
return {
|
|
74
|
+
achievements,
|
|
75
|
+
unlockedCount: totalUnlocked,
|
|
76
|
+
totalCount: achievements.length,
|
|
77
|
+
recentlyEarned: newlyEarned,
|
|
78
|
+
nextMilestones,
|
|
79
|
+
completionPercentage
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
function meetsCriteria(achievement, data) {
|
|
83
|
+
const { type, threshold, comparator, customCheck } = achievement.criteria;
|
|
84
|
+
// Handle custom criteria
|
|
85
|
+
if (customCheck) {
|
|
86
|
+
return customCheck(data);
|
|
87
|
+
}
|
|
88
|
+
// Handle standard criteria
|
|
89
|
+
if (threshold === undefined || comparator === undefined) {
|
|
90
|
+
return false;
|
|
91
|
+
}
|
|
92
|
+
const value = extractValue(data, type);
|
|
93
|
+
return compare(value, threshold, comparator);
|
|
94
|
+
}
|
|
95
|
+
function calculateProgress(achievement, data) {
|
|
96
|
+
const { type, threshold, customCheck } = achievement.criteria;
|
|
97
|
+
// Custom checks don't have numeric progress
|
|
98
|
+
if (customCheck) {
|
|
99
|
+
// Try to calculate progress for known patterns
|
|
100
|
+
if (achievement.id === 'early-bird' || achievement.id === 'night-owl') {
|
|
101
|
+
const isEarlyBird = achievement.id === 'early-bird';
|
|
102
|
+
const targetCommits = data.commits.filter(c => {
|
|
103
|
+
const hour = new Date(c.date).getHours();
|
|
104
|
+
if (isEarlyBird) {
|
|
105
|
+
return hour >= 5 && hour < 9;
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
return hour >= 21 || hour < 5;
|
|
109
|
+
}
|
|
110
|
+
}).length;
|
|
111
|
+
return Math.min(100, (targetCommits / 50) * 100);
|
|
112
|
+
}
|
|
113
|
+
// For other custom checks, return 0 or 100
|
|
114
|
+
return meetsCriteria(achievement, data) ? 100 : 0;
|
|
115
|
+
}
|
|
116
|
+
if (threshold === undefined) {
|
|
117
|
+
return 0;
|
|
118
|
+
}
|
|
119
|
+
const current = extractValue(data, type);
|
|
120
|
+
return Math.min(100, (current / threshold) * 100);
|
|
121
|
+
}
|
|
122
|
+
function extractValue(data, type) {
|
|
123
|
+
switch (type) {
|
|
124
|
+
case 'commit-count':
|
|
125
|
+
return data.totalCommits;
|
|
126
|
+
case 'streak':
|
|
127
|
+
return data.streakData.longestStreak.days;
|
|
128
|
+
case 'quality-score':
|
|
129
|
+
return data.commitQuality.overallScore;
|
|
130
|
+
default:
|
|
131
|
+
return 0;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
function compare(value, threshold, comparator) {
|
|
135
|
+
switch (comparator) {
|
|
136
|
+
case '>=':
|
|
137
|
+
return value >= threshold;
|
|
138
|
+
case '>':
|
|
139
|
+
return value > threshold;
|
|
140
|
+
case '==':
|
|
141
|
+
return value === threshold;
|
|
142
|
+
case '<':
|
|
143
|
+
return value < threshold;
|
|
144
|
+
case '<=':
|
|
145
|
+
return value <= threshold;
|
|
146
|
+
default:
|
|
147
|
+
return false;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
function getRecentAchievements(progress, days = 7) {
|
|
151
|
+
const cutoffDate = new Date();
|
|
152
|
+
cutoffDate.setDate(cutoffDate.getDate() - days);
|
|
153
|
+
return progress.achievements
|
|
154
|
+
.filter(a => a.isUnlocked && a.earnedDate && a.earnedDate >= cutoffDate)
|
|
155
|
+
.sort((a, b) => {
|
|
156
|
+
if (!a.earnedDate || !b.earnedDate)
|
|
157
|
+
return 0;
|
|
158
|
+
return b.earnedDate.getTime() - a.earnedDate.getTime();
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
function getAchievementsByCategory(progress, category) {
|
|
162
|
+
return progress.achievements.filter(a => a.category === category);
|
|
163
|
+
}
|
|
164
|
+
function getNextMilestone(progress) {
|
|
165
|
+
const locked = progress.achievements.filter(a => !a.isUnlocked);
|
|
166
|
+
if (locked.length === 0)
|
|
167
|
+
return null;
|
|
168
|
+
return locked.reduce((closest, current) => current.progress > closest.progress ? current : closest);
|
|
169
|
+
}
|