156 lines
5.7 KiB
TypeScript
156 lines
5.7 KiB
TypeScript
import fs from 'fs';
|
|
import path from 'path';
|
|
import archiver from 'archiver';
|
|
import crypto from 'crypto';
|
|
|
|
const BASE64_KEYS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
|
|
const HEXCHAR = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f']
|
|
|
|
var BASE64_VALUES = new Array(123);
|
|
for (let i = 0; i < 123; ++i) BASE64_VALUES[i] = 64;
|
|
for (let i = 0; i < 64; ++i) BASE64_VALUES[BASE64_KEYS.charCodeAt(i)] = i;
|
|
|
|
var _t = ['', '', '', ''];
|
|
var uuidTemplate = _t.concat(_t, '-', _t, '-', _t, '-', _t, '-', _t, _t, _t);
|
|
var indices = uuidTemplate.map(function (value: string, index: number) { return value === '-' ? NaN : index; }).filter(isFinite);
|
|
|
|
export class Utils {
|
|
|
|
private static logLevel: Utils.LogLevel = 1;
|
|
|
|
public static mkdir(dir: string): void {
|
|
if (!fs.existsSync(dir)) {
|
|
let parentDir = path.dirname(dir);
|
|
this.mkdir(parentDir);
|
|
fs.mkdirSync(dir);
|
|
}
|
|
}
|
|
|
|
public static rmdir(dir: string): void {
|
|
if (!fs.existsSync(dir)) return;
|
|
let files = fs.readdirSync(dir);
|
|
for (let item of files) {
|
|
let itemPath = path.join(dir, item);
|
|
let stat = fs.statSync(itemPath);
|
|
stat.isDirectory() ? this.rmdir(itemPath) : fs.unlinkSync(itemPath);
|
|
}
|
|
fs.rmdirSync(dir);
|
|
}
|
|
|
|
public static zipdir(srcDir: string, outputFile: string): Promise<void> {
|
|
Utils.mkdir(path.dirname(outputFile));
|
|
var promise: Promise<void> = new Promise((resolve: () => void, reject: (reason?: any) => void) => {
|
|
let writeStream = fs.createWriteStream(outputFile);
|
|
let archive = archiver('zip', {
|
|
// encoding: 'utf-8',
|
|
// forceZip64: true,
|
|
zlib: { level: 9 }
|
|
});
|
|
writeStream.on('close', () => {
|
|
resolve();
|
|
});
|
|
archive.on('error', function (error: archiver.ArchiverError) {
|
|
reject(error)
|
|
})
|
|
|
|
archive.pipe(writeStream);
|
|
archive.directory(srcDir, false);
|
|
archive.finalize();
|
|
});
|
|
return promise;
|
|
}
|
|
|
|
public static md5dir(dir: string, md5?: Utils.FileMD5[]): Utils.FileMD5[] {
|
|
md5 = md5 || [];
|
|
let files = fs.readdirSync(dir);
|
|
for (let file of files) {
|
|
let filePath = path.join(dir, file);
|
|
let stat = fs.statSync(filePath);
|
|
if (stat.isDirectory()) {
|
|
this.md5dir(filePath, md5)
|
|
} else {
|
|
let buffer = fs.readFileSync(filePath);
|
|
let hash = crypto.createHash('md5');
|
|
hash.update(buffer);
|
|
let hex = hash.digest('hex');
|
|
md5.push({ path: filePath, md5: hex });
|
|
}
|
|
}
|
|
return md5;
|
|
}
|
|
|
|
public static fileMD5Compare(src: Utils.FileMD5[], dst: Utils.FileMD5[]): Utils.FileMD5CompareResult {
|
|
let result: Utils.FileMD5CompareResult = { added: [], deleted: [], changed: [], same: [] };
|
|
let srcCopy = src.concat([]);
|
|
let dstCopy = dst.concat([]);
|
|
|
|
let dstItem: Utils.FileMD5 | undefined;
|
|
while (dstItem = dstCopy.shift()) {
|
|
let foundItem: Utils.FileMD5 | undefined = undefined;
|
|
for (let j = 0, srcLenght = srcCopy.length; j < srcLenght; j++) {
|
|
let srcItem = srcCopy[j];
|
|
if (srcItem.path === dstItem.path) {
|
|
foundItem = srcItem;
|
|
srcCopy.splice(j, 1);
|
|
break;
|
|
}
|
|
}
|
|
if (!foundItem) {
|
|
result.added.push(dstItem);
|
|
} else {
|
|
foundItem.md5 === dstItem.md5 ? result.same.push(dstItem) : result.changed.push(dstItem)
|
|
}
|
|
}
|
|
result.deleted.push(...srcCopy);
|
|
return result;
|
|
}
|
|
|
|
public static setLogLevel(level: Utils.LogLevel): void {
|
|
Utils.logLevel = level;
|
|
}
|
|
|
|
public static log(text: string, level: Utils.LogLevel.Simple | Utils.LogLevel.Particular = Utils.LogLevel.Simple): void {
|
|
if (Utils.logLevel === Utils.LogLevel.Disable) return;
|
|
if (level <= Utils.logLevel) {
|
|
console.log(text);
|
|
}
|
|
}
|
|
|
|
public static toBase64(uuid: string) {
|
|
let j = 2;
|
|
let base64 = uuid.substring(0, j)
|
|
for (let i = 2; i < 22; i += 2) {
|
|
let hex1 = HEXCHAR.indexOf(uuid.charAt(indices[j++]));
|
|
let hex2 = HEXCHAR.indexOf(uuid.charAt(indices[j++]));
|
|
let hex3 = HEXCHAR.indexOf(uuid.charAt(indices[j++]));
|
|
let lhs = (hex1 << 2) | (hex2 >> 2);
|
|
let rhs = ((hex2 & 3) << 4) | hex3;
|
|
base64 += BASE64_KEYS.charAt(lhs);
|
|
base64 += BASE64_KEYS.charAt(rhs);
|
|
}
|
|
return base64;
|
|
}
|
|
|
|
public static toUUID(base64: string) {
|
|
let baselen = base64.length;
|
|
if (baselen < 22) {
|
|
return base64;
|
|
}
|
|
uuidTemplate[0] = base64[0];
|
|
uuidTemplate[1] = base64[1];
|
|
for (let i = 2, j = 2; i < 22; i += 2) {
|
|
let lhs = BASE64_VALUES[base64.charCodeAt(i)];
|
|
let rhs = BASE64_VALUES[base64.charCodeAt(i + 1)];
|
|
uuidTemplate[indices[j++]] = HEXCHAR[lhs >> 2];
|
|
uuidTemplate[indices[j++]] = HEXCHAR[((lhs & 3) << 2) | rhs >> 4];
|
|
uuidTemplate[indices[j++]] = HEXCHAR[rhs & 0xF];
|
|
}
|
|
return uuidTemplate.join('');
|
|
}
|
|
}
|
|
|
|
export namespace Utils {
|
|
export type FileMD5 = { path: string, md5: string };
|
|
export type FileMD5CompareResult = { added: FileMD5[], deleted: FileMD5[], changed: FileMD5[], same: FileMD5[] }
|
|
export enum LogLevel { Disable = 0, Simple = 1, Particular = 2 };
|
|
} |