/** * BetterDiscord Utils Module * Copyright (c) 2015-present Jiiks/JsSucks - https://github.com/Jiiks / https://github.com/JsSucks * All rights reserved. * https://betterdiscord.net * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ const path = require('path'), fs = require('fs'), _ = require('lodash'); import { Vendor } from 'modules'; import filetype from 'file-type'; export class Utils { static overload(fn, cb) { const orig = fn; return function (...args) { orig(...args); cb(...args); } } static async tryParseJson(jsonString) { try { return JSON.parse(jsonString); } catch (err) { throw ({ 'message': 'Failed to parse json', err }); } } static toCamelCase(o) { const camelCased = {}; _.forEach(o, (value, key) => { if (_.isPlainObject(value) || _.isArray(value)) { value = this.toCamelCase(value); } camelCased[_.camelCase(key)] = value; }); return camelCased; } static compare(value1, value2) { // Check to see if value1 and value2 contain the same data if (typeof value1 !== typeof value2) return false; if (value1 === null && value2 === null) return true; if (value1 === null || value2 === null) return false; if (typeof value1 === 'object' || typeof value1 === 'array') { // Loop through the object and check if everything's the same let value1array = typeof value1 === 'array' ? value1 : Object.keys(value1); let value2array = typeof value2 === 'array' ? value2 : Object.keys(value2); if (value1array.length !== value2array.length) return false; for (let key in value1) { if (!this.compare(value1[key], value2[key])) return false; } } else if (value1 !== value2) return false; // value1 and value2 contain the same data return true; } } export class FileUtils { static async fileExists(path) { return new Promise((resolve, reject) => { fs.stat(path, (err, stats) => { if (err) return reject({ 'message': `No such file or directory: ${err.path}`, err }); if (!stats.isFile()) return reject({ 'message': `Not a file: ${path}`, stats }); resolve(); }); }); } static async directoryExists(path) { return new Promise((resolve, reject) => { fs.stat(path, (err, stats) => { if (err) return reject({ 'message': `Directory does not exist: ${path}`, err }); if (!stats.isDirectory()) return reject({ 'message': `Not a directory: ${path}`, stats }); resolve(); }); }); } static async createDirectory(path) { return new Promise((resolve, reject) => { fs.mkdir(path, err => { if (err) { if (err.code === 'EEXIST') return resolve(); else return reject(err); } resolve(); }); }); } static async ensureDirectory(path) { try { await this.directoryExists(path); return true; } catch (err) { try { await this.createDirectory(path); return true; } catch (err) { throw err; } } } static async readFile(path) { try { await this.fileExists(path); } catch (err) { throw (err); } return new Promise((resolve, reject) => { fs.readFile(path, 'utf-8', (err, data) => { if (err) reject({ 'message': `Could not read file: ${path}`, err }); resolve(data); }); }); } static async readFileBuffer(path, options) { return new Promise((resolve, reject) => { fs.readFile(path, options || {}, (err, data) => { if (err) return reject(err); resolve(data); }); }); } static async writeFile(path, data) { return new Promise((resolve, reject) => { fs.writeFile(path, data, err => { if (err) return reject(err); resolve(); }); }); } static async readJsonFromFile(path) { let readFile; try { readFile = await this.readFile(path); } catch (err) { throw (err); } try { const parsed = await Utils.tryParseJson(readFile); return parsed; } catch (err) { throw (Object.assign(err, { path })); } } static async writeJsonToFile(path, json) { return this.writeFile(path, JSON.stringify(json)); } static async listDirectory(path) { try { await this.directoryExists(path); return new Promise((resolve, reject) => { fs.readdir(path, (err, files) => { if (err) return reject(err); resolve(files); }); }); } catch (err) { throw err; } } static async readDir(path) { return this.listDirectory(path); } static async getFileType(buffer) { if (typeof buffer === 'string') buffer = await this.readFileBuffer(buffer); return filetype(buffer); } static async toDataURI(buffer, type) { if (typeof buffer === 'string') buffer = await this.readFileBuffer(buffer); if (!type) type = this.getFileType(buffer).mime; return `data:${type};base64,${buffer.toString('base64')}`; } }