@codeplaydata/datasus
Version:
This application decompress the datasus micro data and serve as a gateway class.
72 lines (71 loc) • 3.19 kB
JavaScript
// @filename: DATASUSGenericFTPGateway.ts
/**
* Generic gateway for accessing the DATASUS public FTP.
*
* This abstract class provides a common list and downloads operations from a base
* path (PATH) using an injected FTP client. Specific strategies (e.g., SIA,
* SIH, etc.) should extend this class.
*/
export class DATASUSGenericFTPGateway {
client;
PATH;
/**
* @param client FTP client implementation.
* @param PATH Base path on the FTP where dataset files are located.
*/
constructor(client, PATH) {
this.client = client;
this.PATH = PATH;
}
/**
* Lists files under the base directory applying optional filters for states and period.
* @param input Subset (src) and, optionally, states and period (YYYY-MM).
* @param display 'full' returns the full FTP entry objects, 'short' returns only filenames.
*/
async list(input, display = 'full') {
let list = await this.client.list(this.PATH);
let seq = [];
if ('src' in input && 'states' in input && 'period' in input && 'month' in input.period.start && 'month' in input.period.end) {
if (input.period && input.period.start.year < 2008 || input.period && input.period.end.year > new Date(Date.now()).getFullYear()) {
throw new Error('Invalid Period.');
}
for (let ano = input.period.start.year; ano <= input.period.end.year; ano++) {
const mesInicial = (ano === input.period.start.year) ? parseInt(input.period.start.month, 10) : 1;
const mesFinal = (ano === input.period.end.year) ? parseInt(input.period.end.month, 10) : 12;
for (let mes = mesInicial; mes <= mesFinal; mes++) {
const stringAno = ano.toString().slice(-2);
const stringMes = mes.toString().padStart(2, '0');
seq.push(stringAno + stringMes);
}
}
;
list = seq.map(yearMonth => {
return input.states.map((state) => {
return list.filter((i) => i.name.startsWith(input.src + state + yearMonth));
}).flat();
}).flat();
return display === 'full' ?
list :
list.map((item) => item.name);
}
if ('src' in input && 'states' in input) {
list = input.states.map((state) => {
return list.filter((i) => i.name.startsWith(input.src + state));
}).flat();
return display === 'full' ?
list :
list.map((item) => item.name);
}
return display === 'full' ?
list.filter((i) => i.name.startsWith(input.src)) :
list.filter((i) => i.name.startsWith(input.src)).map((item) => item.name);
}
/**
* Downloads a file from the FTP using the configured PATH as base.
* @param file Remote filename (relative to PATH).
* @param dest Optional local path; if not provided, uses the same filename.
*/
async get(file, dest) {
return await this.client?.download(dest || file, this.PATH + file);
}
}