@cruncheevos/cli
Version:
Maintain achievement sets for RetroAchievements.org using JavaScript, an alternative to RATools
113 lines (112 loc) • 3.93 kB
JavaScript
import { Achievement } from '@cruncheevos/core';
import chalk from 'chalk';
import { log } from './mockable.js';
// This file is called 'lint' as it may be further expanded
// into producing much more warnings on conditions and assets
const allowedPoints = new Set([0, 1, 2, 3, 4, 5, 10, 25, 50, 100]);
function truncateLongString(str, maxLength) {
if (str.length > maxLength) {
return str.slice(0, maxLength) + '...';
}
return str;
}
const checks = {
noLongTitles(set) {
const issues = [];
const maxLength = 255;
for (const asset of set) {
const type = asset instanceof Achievement ? 'Achievement' : 'Leaderboard';
if (asset.title.length > 255) {
issues.push({
type: 'no-long-titles',
badAsset: asset,
message: `${type} "${truncateLongString(asset.title, 40)}" has title length above ` +
`${maxLength}: ${asset.title.length}`,
});
}
}
return issues;
},
noLongDescriptions(set) {
const issues = [];
const maxLength = 255;
for (const asset of set) {
const type = asset instanceof Achievement ? 'Achievement' : 'Leaderboard';
if (asset.description.length > 255) {
issues.push({
type: 'no-long-descriptions',
badAsset: asset,
message: `${type} "${truncateLongString(asset.title, 40)}" has description length above ` +
`${maxLength}: ${asset.description.length}`,
});
}
}
return issues;
},
noOddPoints(set) {
const issues = [];
for (const ach of set.achievements) {
if (allowedPoints.has(ach.points) === false) {
issues.push({
type: 'no-odd-points',
badAsset: ach,
message: `Achievement "${ach.title}" has odd amount of points: ${ach.points}`,
});
}
}
return issues;
},
uniqueAchievementTitlesWithoutId(set) {
const existing = new Map();
const issues = [];
for (const ach of set.achievements) {
const idIsUnique = ach.id < 111000001;
if (idIsUnique) {
continue;
}
if (existing.has(ach.title)) {
issues.push({
type: 'unique-achievement-titles-without-id',
badAsset: ach,
goodAsset: existing.get(ach.title),
message: `There are several achievements without ID titled "${ach.title}"`,
});
}
else {
existing.set(ach.title, ach);
}
}
return issues;
},
uniqueLeaderboardTitlesWithoutId(set) {
const existing = new Map();
const issues = [];
for (const lb of set.leaderboards) {
const idIsUnique = lb.id < 111000001;
if (idIsUnique) {
continue;
}
if (existing.has(lb.title)) {
issues.push({
type: 'unique-leaderboard-titles-without-id',
badAsset: lb,
goodAsset: existing.get(lb.title),
message: `There are several achievements without ID titled "${lb.title}"`,
});
}
else {
existing.set(lb.title, lb);
}
}
return issues;
},
};
function collectIssues(set) {
return Object.values(checks).flatMap(checkFunction => checkFunction(set));
}
export function logWarnings(set) {
const issues = collectIssues(set);
for (const issue of issues) {
log(chalk.yellowBright(`WARN: ${issue.message}`));
}
}