quackscore 0.1.0 → 0.1.1
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/leaderboard.d.ts +1 -1
- package/dist/commands/leaderboard.d.ts.map +1 -1
- package/dist/commands/leaderboard.js +12 -5
- package/dist/commands/leaderboard.js.map +1 -1
- package/dist/commands/mock-report.js +13 -13
- package/dist/commands/mock-report.js.map +1 -1
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/llm/prompts.d.ts.map +1 -1
- package/dist/llm/prompts.js +7 -2
- package/dist/llm/prompts.js.map +1 -1
- package/dist/report/generate.d.ts.map +1 -1
- package/dist/report/generate.js +32 -9
- package/dist/report/generate.js.map +1 -1
- package/dist/report/index.d.ts +1 -0
- package/dist/report/index.d.ts.map +1 -1
- package/dist/report/index.js +1 -0
- package/dist/report/index.js.map +1 -1
- package/dist/report/leaderboard.d.ts +3 -0
- package/dist/report/leaderboard.d.ts.map +1 -0
- package/dist/report/leaderboard.js +486 -0
- package/dist/report/leaderboard.js.map +1 -0
- package/dist/shared/technologies.d.ts +2 -2
- package/dist/shared/technologies.d.ts.map +1 -1
- package/dist/shared/technologies.js +38 -32
- package/dist/shared/technologies.js.map +1 -1
- package/dist/shared/types.d.ts +6 -0
- package/dist/shared/types.d.ts.map +1 -1
- package/dist/storage/index.d.ts +1 -1
- package/dist/storage/index.d.ts.map +1 -1
- package/dist/storage/index.js +1 -1
- package/dist/storage/index.js.map +1 -1
- package/dist/storage/leaderboard.d.ts +1 -0
- package/dist/storage/leaderboard.d.ts.map +1 -1
- package/dist/storage/leaderboard.js +93 -8
- package/dist/storage/leaderboard.js.map +1 -1
- package/dist/storage/paths.d.ts +1 -0
- package/dist/storage/paths.d.ts.map +1 -1
- package/dist/storage/paths.js +1 -0
- package/dist/storage/paths.js.map +1 -1
- package/dist/storage/user.d.ts.map +1 -1
- package/dist/storage/user.js +10 -2
- package/dist/storage/user.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/shared/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEpD,eAAO,MAAM,aAAa,wIAWhB,CAAC;AAEX,MAAM,MAAM,IAAI,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,CAAC,CAAC;AAElD,eAAO,MAAM,0BAA0B,qEAAsE,CAAC;AAE9G,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,0BAA0B,CAAC,CAAC,MAAM,CAAC,CAAC;AAE3E,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,KAAK,EAAE,gBAAgB,EAAE,CAAC;IAC1B,YAAY,EAAE,UAAU,EAAE,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,MAAM;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,iBAAiB,EAAE,MAAM,CAAC;IAC1B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,mBAAmB,EAAE,kBAAkB,EAAE,CAAC;IAC1C,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,QAAQ;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,EAAE,MAAM,EAAE,CAAC;IACd,KAAK,EAAE,WAAW,CAAC;IACnB,SAAS,CAAC,EAAE,gBAAgB,CAAC;CAC9B;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;CACrB"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/shared/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEpD,eAAO,MAAM,aAAa,wIAWhB,CAAC;AAEX,MAAM,MAAM,IAAI,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,CAAC,CAAC;AAElD,eAAO,MAAM,0BAA0B,qEAAsE,CAAC;AAE9G,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,0BAA0B,CAAC,CAAC,MAAM,CAAC,CAAC;AAE3E,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,KAAK,EAAE,gBAAgB,EAAE,CAAC;IAC1B,YAAY,EAAE,UAAU,EAAE,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,MAAM;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,iBAAiB,EAAE,MAAM,CAAC;IAC1B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,mBAAmB,EAAE,kBAAkB,EAAE,CAAC;IAC1C,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,QAAQ;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,EAAE,MAAM,EAAE,CAAC;IACd,KAAK,EAAE,WAAW,CAAC;IACnB,SAAS,CAAC,EAAE,gBAAgB,CAAC;CAC9B;AAED,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB"}
|
package/dist/storage/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { saveUserData, loadUserData } from './user.js';
|
|
2
2
|
export { saveReport, getUserReportPath } from './report.js';
|
|
3
|
-
export { loadLeaderboard } from './leaderboard.js';
|
|
3
|
+
export { loadLeaderboard, saveLeaderboardReport } from './leaderboard.js';
|
|
4
4
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/storage/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/storage/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC"}
|
package/dist/storage/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { saveUserData, loadUserData } from './user.js';
|
|
2
2
|
export { saveReport, getUserReportPath } from './report.js';
|
|
3
|
-
export { loadLeaderboard } from './leaderboard.js';
|
|
3
|
+
export { loadLeaderboard, saveLeaderboardReport } from './leaderboard.js';
|
|
4
4
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/storage/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/storage/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { LeaderboardEntry, UserData } from '../shared/types.js';
|
|
2
2
|
export declare function loadLeaderboard(): LeaderboardEntry[];
|
|
3
3
|
export declare function updateLeaderboard(data: UserData): void;
|
|
4
|
+
export declare function saveLeaderboardReport(html: string): string;
|
|
4
5
|
//# sourceMappingURL=leaderboard.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"leaderboard.d.ts","sourceRoot":"","sources":["../../src/storage/leaderboard.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"leaderboard.d.ts","sourceRoot":"","sources":["../../src/storage/leaderboard.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AA2DrE,wBAAgB,eAAe,IAAI,gBAAgB,EAAE,CAyCpD;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,QAAQ,GAAG,IAAI,CA0BtD;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAI1D"}
|
|
@@ -1,23 +1,103 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
|
-
import
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { ensureStorageDir, LEADERBOARD_FILE, LEADERBOARD_REPORT_FILE, STORAGE_DIR } from './paths.js';
|
|
3
4
|
import { diagLog } from '../shared/diagnostics.js';
|
|
5
|
+
import { normalizeTechnologies } from '../shared/technologies.js';
|
|
6
|
+
const IGNORED_JSON_FILES = new Set(['config.json', 'leaderboard.json']);
|
|
7
|
+
function isUserData(value) {
|
|
8
|
+
if (!value || typeof value !== 'object')
|
|
9
|
+
return false;
|
|
10
|
+
const candidate = value;
|
|
11
|
+
return typeof candidate.username === 'string'
|
|
12
|
+
&& typeof candidate.lastUpdated === 'string'
|
|
13
|
+
&& Array.isArray(candidate.prs)
|
|
14
|
+
&& Boolean(candidate.stats)
|
|
15
|
+
&& typeof candidate.stats?.totalPoints === 'number'
|
|
16
|
+
&& typeof candidate.stats?.level === 'number';
|
|
17
|
+
}
|
|
18
|
+
function normalizeUserData(data) {
|
|
19
|
+
return {
|
|
20
|
+
...data,
|
|
21
|
+
prs: data.prs.map((pr) => pr.analysis
|
|
22
|
+
? {
|
|
23
|
+
...pr,
|
|
24
|
+
analysis: {
|
|
25
|
+
...pr.analysis,
|
|
26
|
+
technologies: normalizeTechnologies(pr.analysis.technologies),
|
|
27
|
+
},
|
|
28
|
+
}
|
|
29
|
+
: pr),
|
|
30
|
+
stats: {
|
|
31
|
+
...data.stats,
|
|
32
|
+
technologies: Object.fromEntries(normalizeTechnologies(Object.keys(data.stats.technologies)).map((key) => [key, data.stats.technologies[key] ?? 0])),
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
function toLeaderboardEntry(storageKey, data) {
|
|
37
|
+
const areaEntries = Object.entries(data.stats.areas).sort(([, left], [, right]) => right - left);
|
|
38
|
+
const reportPath = path.join(STORAGE_DIR, `${storageKey}.html`);
|
|
39
|
+
return {
|
|
40
|
+
storageKey,
|
|
41
|
+
username: data.username,
|
|
42
|
+
totalPoints: data.stats.totalPoints,
|
|
43
|
+
level: data.stats.level,
|
|
44
|
+
lastUpdated: data.lastUpdated,
|
|
45
|
+
analyzedPRs: data.stats.analyzedPRs,
|
|
46
|
+
primaryArea: areaEntries[0]?.[0],
|
|
47
|
+
title: data.character?.title,
|
|
48
|
+
summary: data.character?.summary,
|
|
49
|
+
reportPath: fs.existsSync(reportPath) ? reportPath : undefined,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
4
52
|
export function loadLeaderboard() {
|
|
5
53
|
ensureStorageDir();
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
54
|
+
const legacyExists = fs.existsSync(LEADERBOARD_FILE);
|
|
55
|
+
const files = fs.readdirSync(STORAGE_DIR, { withFileTypes: true })
|
|
56
|
+
.filter((entry) => entry.isFile() && entry.name.endsWith('.json') && !IGNORED_JSON_FILES.has(entry.name))
|
|
57
|
+
.map((entry) => entry.name);
|
|
58
|
+
diagLog('Loading leaderboard from stored profile files', {
|
|
59
|
+
storageDir: STORAGE_DIR,
|
|
60
|
+
profileFileCount: files.length,
|
|
61
|
+
legacyLeaderboardFile: LEADERBOARD_FILE,
|
|
62
|
+
legacyExists,
|
|
63
|
+
});
|
|
64
|
+
const entries = files.flatMap((fileName) => {
|
|
65
|
+
const filePath = path.join(STORAGE_DIR, fileName);
|
|
66
|
+
try {
|
|
67
|
+
const raw = fs.readFileSync(filePath, 'utf-8');
|
|
68
|
+
const parsed = JSON.parse(raw);
|
|
69
|
+
if (!isUserData(parsed)) {
|
|
70
|
+
diagLog('Skipping non-user JSON file while building leaderboard', { filePath });
|
|
71
|
+
return [];
|
|
72
|
+
}
|
|
73
|
+
const normalized = normalizeUserData(parsed);
|
|
74
|
+
return [toLeaderboardEntry(path.basename(fileName, '.json'), normalized)];
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
diagLog('Skipping unreadable leaderboard profile', {
|
|
78
|
+
filePath,
|
|
79
|
+
message: error instanceof Error ? error.message : String(error),
|
|
80
|
+
});
|
|
81
|
+
return [];
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
return entries.sort((left, right) => right.totalPoints - left.totalPoints
|
|
85
|
+
|| right.analyzedPRs - left.analyzedPRs
|
|
86
|
+
|| Date.parse(right.lastUpdated) - Date.parse(left.lastUpdated)
|
|
87
|
+
|| left.username.localeCompare(right.username));
|
|
13
88
|
}
|
|
14
89
|
export function updateLeaderboard(data) {
|
|
15
90
|
const leaderboard = loadLeaderboard();
|
|
16
91
|
const entry = {
|
|
92
|
+
storageKey: data.username,
|
|
17
93
|
username: data.username,
|
|
18
94
|
totalPoints: data.stats.totalPoints,
|
|
19
95
|
level: data.stats.level,
|
|
20
96
|
lastUpdated: data.lastUpdated,
|
|
97
|
+
analyzedPRs: data.stats.analyzedPRs,
|
|
98
|
+
primaryArea: Object.entries(data.stats.areas).sort(([, left], [, right]) => right - left)[0]?.[0],
|
|
99
|
+
title: data.character?.title,
|
|
100
|
+
summary: data.character?.summary,
|
|
21
101
|
};
|
|
22
102
|
const idx = leaderboard.findIndex((e) => e.username === data.username);
|
|
23
103
|
if (idx >= 0) {
|
|
@@ -34,4 +114,9 @@ export function updateLeaderboard(data) {
|
|
|
34
114
|
});
|
|
35
115
|
fs.writeFileSync(LEADERBOARD_FILE, JSON.stringify(leaderboard, null, 2), 'utf-8');
|
|
36
116
|
}
|
|
117
|
+
export function saveLeaderboardReport(html) {
|
|
118
|
+
ensureStorageDir();
|
|
119
|
+
fs.writeFileSync(LEADERBOARD_REPORT_FILE, html, 'utf-8');
|
|
120
|
+
return LEADERBOARD_REPORT_FILE;
|
|
121
|
+
}
|
|
37
122
|
//# sourceMappingURL=leaderboard.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"leaderboard.js","sourceRoot":"","sources":["../../src/storage/leaderboard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"leaderboard.js","sourceRoot":"","sources":["../../src/storage/leaderboard.ts"],"names":[],"mappings":"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"}
|
package/dist/storage/paths.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export declare const STORAGE_DIR: string;
|
|
2
2
|
export declare const LEADERBOARD_FILE: string;
|
|
3
|
+
export declare const LEADERBOARD_REPORT_FILE: string;
|
|
3
4
|
export declare function ensureStorageDir(): void;
|
|
4
5
|
export declare function userFilePath(username: string): string;
|
|
5
6
|
export declare function userReportPath(username: string): string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/storage/paths.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,WAAW,QAAyC,CAAC;AAClE,eAAO,MAAM,gBAAgB,QAA6C,CAAC;
|
|
1
|
+
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/storage/paths.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,WAAW,QAAyC,CAAC;AAClE,eAAO,MAAM,gBAAgB,QAA6C,CAAC;AAC3E,eAAO,MAAM,uBAAuB,QAA6C,CAAC;AAElF,wBAAgB,gBAAgB,IAAI,IAAI,CAKvC;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAErD;AAED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEvD"}
|
package/dist/storage/paths.js
CHANGED
|
@@ -4,6 +4,7 @@ import os from 'os';
|
|
|
4
4
|
import { diagLog } from '../shared/diagnostics.js';
|
|
5
5
|
export const STORAGE_DIR = path.join(os.homedir(), '.quackscore');
|
|
6
6
|
export const LEADERBOARD_FILE = path.join(STORAGE_DIR, 'leaderboard.json');
|
|
7
|
+
export const LEADERBOARD_REPORT_FILE = path.join(STORAGE_DIR, 'leaderboard.html');
|
|
7
8
|
export function ensureStorageDir() {
|
|
8
9
|
if (!fs.existsSync(STORAGE_DIR)) {
|
|
9
10
|
diagLog('Creating storage directory', { storageDir: STORAGE_DIR });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/storage/paths.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AAEnD,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,aAAa,CAAC,CAAC;AAClE,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,kBAAkB,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/storage/paths.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AAEnD,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,aAAa,CAAC,CAAC;AAClE,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,kBAAkB,CAAC,CAAC;AAC3E,MAAM,CAAC,MAAM,uBAAuB,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,kBAAkB,CAAC,CAAC;AAElF,MAAM,UAAU,gBAAgB;IAC9B,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAChC,OAAO,CAAC,4BAA4B,EAAE,EAAE,UAAU,EAAE,WAAW,EAAE,CAAC,CAAC;QACnE,EAAE,CAAC,SAAS,CAAC,WAAW,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACjD,CAAC;AACH,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,QAAgB;IAC3C,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,QAAQ,OAAO,CAAC,CAAC;AACpD,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,QAAgB;IAC7C,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,QAAQ,OAAO,CAAC,CAAC;AACpD,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user.d.ts","sourceRoot":"","sources":["../../src/storage/user.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"user.d.ts","sourceRoot":"","sources":["../../src/storage/user.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAKnD,wBAAgB,YAAY,CAAC,IAAI,EAAE,QAAQ,GAAG,IAAI,CAYjD;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CAQ9D"}
|
package/dist/storage/user.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
2
|
import { ensureStorageDir, userFilePath } from './paths.js';
|
|
3
|
-
import { updateLeaderboard } from './leaderboard.js';
|
|
4
3
|
import { diagLog } from '../shared/diagnostics.js';
|
|
5
4
|
import { normalizeTechnologies } from '../shared/technologies.js';
|
|
6
5
|
export function saveUserData(data) {
|
|
@@ -15,7 +14,6 @@ export function saveUserData(data) {
|
|
|
15
14
|
level: normalized.stats.level,
|
|
16
15
|
});
|
|
17
16
|
fs.writeFileSync(filePath, JSON.stringify(normalized, null, 2), 'utf-8');
|
|
18
|
-
updateLeaderboard(normalized);
|
|
19
17
|
}
|
|
20
18
|
export function loadUserData(username) {
|
|
21
19
|
const file = userFilePath(username);
|
|
@@ -28,8 +26,18 @@ export function loadUserData(username) {
|
|
|
28
26
|
return normalizeUserData(JSON.parse(raw));
|
|
29
27
|
}
|
|
30
28
|
function normalizeUserData(data) {
|
|
29
|
+
const normalizedTechnologyTotals = {};
|
|
30
|
+
for (const [technology, points] of Object.entries(data.stats.technologies ?? {})) {
|
|
31
|
+
for (const normalized of normalizeTechnologies([technology])) {
|
|
32
|
+
normalizedTechnologyTotals[normalized] = (normalizedTechnologyTotals[normalized] || 0) + points;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
31
35
|
return {
|
|
32
36
|
...data,
|
|
37
|
+
stats: {
|
|
38
|
+
...data.stats,
|
|
39
|
+
technologies: normalizedTechnologyTotals,
|
|
40
|
+
},
|
|
33
41
|
prs: data.prs.map((pr) => pr.analysis
|
|
34
42
|
? {
|
|
35
43
|
...pr,
|
package/dist/storage/user.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user.js","sourceRoot":"","sources":["../../src/storage/user.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AAEpB,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC5D,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"user.js","sourceRoot":"","sources":["../../src/storage/user.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AAEpB,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC5D,OAAO,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AACnD,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAElE,MAAM,UAAU,YAAY,CAAC,IAAc;IACzC,gBAAgB,EAAE,CAAC;IACnB,MAAM,QAAQ,GAAG,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC7C,MAAM,UAAU,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;IAC3C,OAAO,CAAC,wBAAwB,EAAE;QAChC,QAAQ,EAAE,UAAU,CAAC,QAAQ;QAC7B,QAAQ;QACR,OAAO,EAAE,UAAU,CAAC,GAAG,CAAC,MAAM;QAC9B,WAAW,EAAE,UAAU,CAAC,KAAK,CAAC,WAAW;QACzC,KAAK,EAAE,UAAU,CAAC,KAAK,CAAC,KAAK;KAC9B,CAAC,CAAC;IACH,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;AAC3E,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,QAAgB;IAC3C,MAAM,IAAI,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;IACpC,MAAM,MAAM,GAAG,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;IACnC,OAAO,CAAC,wBAAwB,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;IACxE,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IACzB,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC3C,OAAO,CAAC,gCAAgC,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;IAC3E,OAAO,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAa,CAAC,CAAC;AACxD,CAAC;AAED,SAAS,iBAAiB,CAAC,IAAc;IACvC,MAAM,0BAA0B,GAA2B,EAAE,CAAC;IAE9D,KAAK,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,IAAI,EAAE,CAAC,EAAE,CAAC;QACjF,KAAK,MAAM,UAAU,IAAI,qBAAqB,CAAC,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC;YAC7D,0BAA0B,CAAC,UAAU,CAAC,GAAG,CAAC,0BAA0B,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,GAAG,MAAM,CAAC;QAClG,CAAC;IACH,CAAC;IAED,OAAO;QACL,GAAG,IAAI;QACP,KAAK,EAAE;YACL,GAAG,IAAI,CAAC,KAAK;YACb,YAAY,EAAE,0BAA0B;SACzC;QACD,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CACvB,EAAE,CAAC,QAAQ;YACT,CAAC,CAAC;gBACE,GAAG,EAAE;gBACL,QAAQ,EAAE;oBACR,GAAG,EAAE,CAAC,QAAQ;oBACd,YAAY,EAAE,qBAAqB,CAAC,EAAE,CAAC,QAAQ,CAAC,YAAY,CAAC;iBAC9D;aACF;YACH,CAAC,CAAC,EAAE,CACP;KACF,CAAC;AACJ,CAAC"}
|