-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstates.mjs
87 lines (71 loc) · 2.49 KB
/
states.mjs
1
2
3
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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
import fs from 'fs/promises';
import path from 'path';
import loadYaml from '../utils/loadYaml.mjs';
import { fileURLToPath } from 'url';
import frontMatter from 'front-matter';
import serveVirtualFile from '../utils/serveVirtualFile.mjs';
import pointPercentage from '../utils/percentage.mjs';
import { getCategories } from './categories.mjs';
import markdown from '../utils/markdown.mjs';
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const statesDir = path.join(__dirname, 'states');
const criteriaFile = path.join(__dirname, 'criteria.yml');
let idCounter = 0;
export async function getStates() {
const categories = await getCategories();
const criteria = await loadYaml(criteriaFile);
const stateFiles = (await fs.readdir(statesDir))
.filter((f) => f.endsWith('.md'))
.map((file) => path.join(statesDir, file));
const states = await Promise.all(
stateFiles.map(async (file) => {
const state = await fs.readFile(file, 'utf8');
const { attributes, body } = frontMatter(state);
const description = markdown(body);
const text = attributes.text ? markdown(attributes.text, true) : null;
const slug = path.basename(file, '.md');
const performance = categories.map((category) => {
const details = attributes.criteria
?.filter((c) => category.criteriaTitles.includes(c.title))
.map((criterium) => {
const { maxPoints, description } = criteria.find(
(c) => c.title === criterium.title,
);
return {
...criterium,
maxPoints,
description: markdown(description, true),
id: idCounter++,
};
});
const achievedPoints = getPoints(attributes, category.criteriaTitles);
const percentage = pointPercentage(achievedPoints, category.maxPoints);
return {
categorySlug: category.slug,
details,
achievedPoints,
percentage,
};
});
return {
...attributes,
text,
slug,
description,
performance,
};
}),
);
return states;
}
export function getPoints(state, criteriaTitles) {
let achievedPoints = 0;
if (state.criteria) {
const stateCriteria = state.criteria.filter((c) =>
criteriaTitles.includes(c.title),
);
achievedPoints = stateCriteria.reduce((a, c) => a + (c.points ?? 0), 0);
}
return achievedPoints;
}
export default serveVirtualFile('states', getStates);