igir
Version:
🕹 A zero-setup ROM collection manager that sorts, filters, extracts or archives, patches, and reports on collections of any size on any OS.
67 lines (66 loc) • 2.83 kB
JavaScript
import path from 'node:path';
import { ProgressBarSymbol } from '../console/progressBar.js';
import FsPoly from '../polyfill/fsPoly.js';
import IgirHeader from '../types/dats/igirHeader.js';
import LogiqxDAT from '../types/dats/logiqx/logiqxDat.js';
import Module from './module.js';
/**
* Write a DAT that was generated by {@link DATGameInferrer} to disk.
*/
export default class Dir2DatCreator extends Module {
options;
constructor(options, progressBar) {
super(progressBar, Dir2DatCreator.name);
this.options = options;
}
/**
* Write the DAT.
*/
async create(dat, candidates) {
if (!this.options.shouldDir2Dat()) {
return undefined;
}
if (candidates.length === 0) {
this.progressBar.logTrace(`${dat.getName()}: no candidates to create dir2dat for`);
return undefined;
}
this.progressBar.logTrace(`${dat.getName()}: writing dir2dat`);
this.progressBar.setSymbol(ProgressBarSymbol.WRITING);
this.progressBar.resetProgress(1);
/**
* It is possible that the {@link ROM} embedded within {@link WriteCandidate}s has been
* manipulated, such as from {@link CandidateExtensionCorrector}. Use the {@link Game}s and
* {@link ROM}s from the {@link WriteCandidate}s instead of the original {@link DAT}.
*/
const gamesToCandidates = candidates.reduce((map, candidate) => {
const key = candidate.getGame();
if (map.has(key)) {
map.get(key)?.push(candidate);
}
else {
map.set(key, [candidate]);
}
return map;
}, new Map());
const gamesFromCandidates = [...gamesToCandidates.entries()].map(([game, candidates]) => {
const roms = candidates
.at(0)
?.getRomsWithFiles()
.map((romWithFiles) => romWithFiles.getRom());
return game.withProps({ roms: roms });
});
const dir2datDir = this.options.getDir2DatOutput();
if (!(await FsPoly.exists(dir2datDir))) {
await FsPoly.mkdir(dir2datDir, { recursive: true });
}
// Construct a new DAT and write it to the output dir
const header = new IgirHeader('dir2dat', dat, this.options);
const dir2dat = new LogiqxDAT({ header, games: gamesFromCandidates });
const dir2datContents = dir2dat.toXmlDat();
const dir2datPath = path.join(dir2datDir, dir2dat.getFilename());
this.progressBar.logInfo(`${dir2dat.getName()}: creating dir2dat '${dir2datPath}'`);
await FsPoly.writeFile(dir2datPath, dir2datContents);
this.progressBar.logTrace(`${dir2dat.getName()}: done writing dir2dat`);
return dir2datPath;
}
}