UNPKG

@codeplaydata/datasus

Version:

This application decompress the datasus micro data and serve as a gateway class.

72 lines (71 loc) 3.19 kB
// @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); } }