import * as fs from 'fs-extra-promise'; import * as Promise from 'bluebird'; import * as path from 'path'; import * as logger from 'winston'; const presentationSizeLimitMb: number = 500; const fileSizeLimitMb: number = 100; const defaultIgnoredPaths: string[] = ['node_modules', 'components', '.git', 'build']; export default function validateSize(presentationPath: string, ignoredPaths: string[] = defaultIgnoredPaths): Promise { return getPresentationSize(presentationPath, ignoredPaths).then(validatePresentationSize); } function getPresentationSize(directoryPath: string, ignoredPaths: string[]): Promise { let presentationSize = 0; return listDirectory(directoryPath, ignoredPaths, (filePath: string, stat: fs.Stats) => { const fileSize = stat.size; validateFileSize(filePath, fileSize); presentationSize += fileSize; }).then(() => presentationSize); } function listDirectory(dir: string, ignoredPaths: string[], cb: (filePath: string, stat: fs.Stats) => void): Promise { return getAllFilesInDirectory(dir).then((filesInDirectory: string[]) => { const filteredFiles = filesInDirectory.filter(fileName => !isIgnoredFile(fileName, ignoredPaths)); return Promise.all(filteredFiles.map(fileName => { const fullFilePath = path.join(dir, fileName); return getStat(fullFilePath).then(stat => { if (stat.isDirectory()) { return listDirectory(fullFilePath, ignoredPaths, cb); } return cb(fullFilePath, stat); }); })); }).then(() => {});; } function isIgnoredFile(fileName: string, ignoredPaths: string[]): boolean { return ignoredPaths.some(file => file === fileName); } function getStat(input: string): Promise { return fs.statAsync(input); } function getAllFilesInDirectory(directoryPath: string): Promise { return fs.readdirAsync(directoryPath); } function validatePresentationSize(presentationSize: number): void { let message = `Size validation issue: presentation exceeded max size limit(${presentationSizeLimitMb} MB).`; validate(presentationSizeLimitMb, presentationSize, message); } function validateFileSize(filePath: string, fileSize: number): void { const message = `Size validation issue: file exceeded max size limit(${fileSizeLimitMb} MB), file: ${filePath}`; validate(fileSizeLimitMb, fileSize, message); } function validate(limit: number, size: number, message: string) { const limitInBytes = convertToBytes(limit); if (size > limitInBytes) { logger.warn(message); } } function convertToBytes(megabytes: number): number { return megabytes * 1000000; }