Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

metarhia-common

Package Overview
Dependencies
Maintainers
3
Versions
38
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

metarhia-common - npm Package Compare versions

Comparing version 0.0.12 to 0.0.13

14

common.js
'use strict';
const api = {};
api.os = require('os');
api.path = require('path');
api.events = require('events');
api.crypto = require('crypto');
api.common = {};
module.exports = api.common;

@@ -23,7 +16,4 @@ const submodules = [

'cache', // Cache (enhanced Map)
];
].map(path => './lib/' + path).map(require);
submodules
.map(path => './lib/' + path)
.map(require)
.map(exports => exports(api));
module.exports = Object.assign({}, ...submodules);

24

lib/array.js
'use strict';
module.exports = (api) => {
const splitAt = (
// Splits array into two parts
index, // index defining end of first part and start of second
array // array which is splitting
// Returns tuple with two parts of the array
) => {
const part1 = array.slice(0, index);
const part2 = array.slice(index, array.length);
return [part1, part2];
};
api.common.splitAt = (
// Splits array into two parts
index, // index defining end of first part and start of second
array // array which is splitting
// Returns tuple with two parts of the array
) => {
const part1 = array.slice(0, index);
const part2 = array.slice(index, array.length);
return [part1, part2];
};
module.exports = {
splitAt
};
'use strict';
module.exports = (api) => {
const withClear = (
cache // mixin to this Map
) => {
api.common.cache = (
// Extend Map interface total allocated size: map.allocated
options // { calcSize }
) => {
const cache = new Map();
const calcSize = (options && options.calcSize) || false;
cache.add = cache.set;
if (calcSize) api.common.cache.withSize(cache);
else api.common.cache.withClear(cache);
cache.del = cache.delete;
return cache;
cache.clr = (
prefix, // string to compare with key start
fn // listener function `(key)` on delete key
) => {
let key;
for (key of cache.keys()) {
if (key.startsWith(prefix)) {
cache.delete(key);
if (fn) fn(key);
}
}
};
api.common.cache.withClear = (
cache // mixin to this Map
) => {
};
cache.add = cache.set;
const withSize = (
cache // mixin to this Map
) => {
cache.del = cache.delete;
cache.allocated = 0;
cache.clr = (
prefix, // string to compare with key start
fn // listener function `(key)` on delete key
) => {
let key;
for (key of cache.keys()) {
if (key.startsWith(prefix)) {
cache.delete(key);
if (fn) fn(key);
}
}
};
const dataSize = data => (data && data.length ? data.length : 0);
cache.add = (key, val) => {
if (cache.has(key)) {
const prev = cache.get(key);
cache.allocated -= dataSize(prev);
}
cache.allocated += dataSize(val);
cache.set(key, val);
};
api.common.cache.withSize = (
cache // mixin to this Map
cache.del = (key) => {
if (cache.has(key)) {
const val = cache.get(key);
cache.allocated -= dataSize(val);
}
};
cache.clr = (
prefix, // string to compare with key start
fn // function `(key, val)` to be called on each key (optional)
) => {
cache.allocated = 0;
const dataSize = data => (data && data.length ? data.length : 0);
cache.add = (key, val) => {
if (cache.has(key)) {
const prev = cache.get(key);
cache.allocated -= dataSize(prev);
}
cache.allocated += dataSize(val);
cache.set(key, val);
};
cache.del = (key) => {
if (cache.has(key)) {
const val = cache.get(key);
cache.forEach((val, key) => {
if (key.startsWith(prefix)) {
cache.allocated -= dataSize(val);
cache.delete(key);
if (fn) fn(key, val);
}
};
});
};
cache.clr = (
prefix, // string to compare with key start
fn // function `(key, val)` to be called on each key (optional)
) => {
cache.forEach((val, key) => {
if (key.startsWith(prefix)) {
cache.allocated -= dataSize(val);
cache.delete(key);
if (fn) fn(key, val);
}
});
};
};
};
const cache = (
// Extend Map interface total allocated size: map.allocated
options // { calcSize }
) => {
const cache = new Map();
const calcSize = (options && options.calcSize) || false;
if (calcSize) withSize(cache);
else withClear(cache);
return cache;
};
module.exports = {
cache
};
'use strict';
module.exports = (api) => {
const SCALAR_TYPES = ['boolean', 'number', 'string'];
const SCALAR_TYPES = ['boolean', 'number', 'string'];
const isScalar = variable => SCALAR_TYPES.includes(typeof(variable));
api.common.isScalar = variable => SCALAR_TYPES.includes(typeof(variable));
const copy = (
// Copy dataset, copy objects to new array
ds // array, source dataset
) => ds.slice();
/* TODO: test speed in following implementations:
1. slice() and slice(0)
2. [].concat(arr);
3. following solution:
let result = [],
l1 = ds.length;
for (i = 0; i < l1; i++) {
result.push(ds[i]);
}
return result;
*/
api.common.copy = (
// Copy dataset, copy objects to new array
ds // array, source dataset
) => ds.slice();
/* TODO: test speed in following implementations:
1. slice() and slice(0)
2. [].concat(arr);
3. following solution:
let result = [],
l1 = ds.length;
for (i = 0; i < l1; i++) {
result.push(ds[i]);
}
return result;
*/
const clone = (
// Clone object
obj // object or array
) => {
if (typeof(obj) !== 'object' || obj === null) return obj;
return Array.isArray(obj) ? cloneArray(obj) : cloneObject(obj);
};
api.common.clone = (
// Clone object
obj // object or array
) => {
if (typeof(obj) !== 'object' || obj === null) return obj;
return Array.isArray(obj) ? cloneArray(obj) : cloneObject(obj);
};
function cloneArray(arr) {
const size = arr.length;
const array = new Array(size);
let i, val;
for (i = 0; i < size; i++) {
val = arr[i];
if (typeof(val) !== 'object' || val === null) {
array[i] = val;
} else if (Array.isArray(val)) {
array[i] = cloneArray(val);
} else {
array[i] = cloneObject(val);
}
function cloneArray(arr) {
const size = arr.length;
const array = new Array(size);
let i, val;
for (i = 0; i < size; i++) {
val = arr[i];
if (typeof(val) !== 'object' || val === null) {
array[i] = val;
} else if (Array.isArray(val)) {
array[i] = cloneArray(val);
} else {
array[i] = cloneObject(val);
}
return array;
}
return array;
}
function cloneObject(obj) {
const object = {};
const keys = Object.keys(obj);
const size = keys.length;
let i, key, val;
for (i = 0; i < size; i++) {
key = keys[i];
val = obj[key];
if (typeof(val) !== 'object' || val === null) {
object[key] = val;
} else if (Array.isArray(val)) {
object[key] = cloneArray(val);
} else {
object[key] = cloneObject(val);
}
function cloneObject(obj) {
const object = {};
const keys = Object.keys(obj);
const size = keys.length;
let i, key, val;
for (i = 0; i < size; i++) {
key = keys[i];
val = obj[key];
if (typeof(val) !== 'object' || val === null) {
object[key] = val;
} else if (Array.isArray(val)) {
object[key] = cloneArray(val);
} else {
object[key] = cloneObject(val);
}
return object;
}
return object;
}
api.common.duplucate = (
// Duplicate object
obj // object or array
) => {
if (typeof(obj) !== 'object' || obj === null) return obj;
const references = new Map();
const dup = Array.isArray(obj) ? duplicateArray : duplicateObject;
return dup(obj, references);
};
const duplucate = (
// Duplicate object
obj // object or array
) => {
if (typeof(obj) !== 'object' || obj === null) return obj;
const references = new Map();
const dup = Array.isArray(obj) ? duplicateArray : duplicateObject;
return dup(obj, references);
};
function duplicateArray(arr, references) {
const size = arr.length;
const array = new Array(size);
references.set(arr, array);
let i, val;
for (i = 0; i < size; i++) {
val = arr[i];
if (references.has(val)) {
array[i] = references.get(val);
} else if (typeof(val) !== 'object' || val === null) {
array[i] = val;
} else if (Array.isArray(val)) {
array[i] = duplicateArray(val, references);
} else {
array[i] = duplicateObject(val, references);
}
function duplicateArray(arr, references) {
const size = arr.length;
const array = new Array(size);
references.set(arr, array);
let i, val;
for (i = 0; i < size; i++) {
val = arr[i];
if (references.has(val)) {
array[i] = references.get(val);
} else if (typeof(val) !== 'object' || val === null) {
array[i] = val;
} else if (Array.isArray(val)) {
array[i] = duplicateArray(val, references);
} else {
array[i] = duplicateObject(val, references);
}
return array;
}
return array;
}
function duplicateObject(obj, references) {
const object = (
obj.constructor ? new obj.constructor() : Object.create(null)
);
references.set(obj, object);
const keys = Object.keys(obj);
const size = keys.length;
let i, key, val;
for (i = 0; i < size; i++) {
key = keys[i];
val = obj[key];
if (references.has(val)) {
object[key] = references.get(val);
} else if (typeof(val) !== 'object' || val === null) {
object[key] = val;
} else if (Array.isArray(val)) {
object[key] = duplicateArray(val, references);
} else {
object[key] = duplicateObject(val, references);
}
function duplicateObject(obj, references) {
const object = (
obj.constructor ? new obj.constructor() : Object.create(null)
);
references.set(obj, object);
const keys = Object.keys(obj);
const size = keys.length;
let i, key, val;
for (i = 0; i < size; i++) {
key = keys[i];
val = obj[key];
if (references.has(val)) {
object[key] = references.get(val);
} else if (typeof(val) !== 'object' || val === null) {
object[key] = val;
} else if (Array.isArray(val)) {
object[key] = duplicateArray(val, references);
} else {
object[key] = duplicateObject(val, references);
}
return object;
}
return object;
}
api.common.getByPath = (
// Read property by dot-separated path
data, // object
dataPath // string, dot-separated path
) => {
const path = dataPath.split('.');
let obj = data;
let i, len, next, prop;
for (i = 0, len = path.length; i < len; i++) {
prop = path[i];
next = obj[prop];
if (next === undefined || next === null) return next;
const getByPath = (
// Read property by dot-separated path
data, // object
dataPath // string, dot-separated path
) => {
const path = dataPath.split('.');
let obj = data;
let i, len, next, prop;
for (i = 0, len = path.length; i < len; i++) {
prop = path[i];
next = obj[prop];
if (next === undefined || next === null) return next;
obj = next;
}
return obj;
};
const setByPath = (
// Set property by dot-separated path
data, // object
dataPath, // string, dot-separated path
value // new value
) => {
const path = dataPath.split('.');
let obj = data;
let i, len, next, prop;
for (i = 0, len = path.length; i < len; i++) {
prop = path[i];
next = obj[prop];
if (i === path.length - 1) {
obj[prop] = value;
return true;
} else {
if (next === undefined || next === null) {
if (typeof(obj) !== 'object') return false;
next = {};
obj[prop] = next;
}
obj = next;
}
return obj;
};
}
return false;
};
api.common.setByPath = (
// Set property by dot-separated path
data, // object
dataPath, // string, dot-separated path
value // new value
) => {
const path = dataPath.split('.');
let obj = data;
let i, len, next, prop;
for (i = 0, len = path.length; i < len; i++) {
prop = path[i];
next = obj[prop];
if (i === path.length - 1) {
obj[prop] = value;
const deleteByPath = (
// Delete property by dot-separated path
data, // object
dataPath // string, dot-separated path
) => {
const path = dataPath.split('.');
let obj = data;
let i, len, next, prop;
for (i = 0, len = path.length; i < len; i++) {
prop = path[i];
next = obj[prop];
if (i === path.length - 1) {
if (obj.hasOwnProperty(prop)) {
delete obj[prop];
return true;
} else {
if (next === undefined || next === null) {
if (typeof(obj) !== 'object') return false;
next = {};
obj[prop] = next;
}
obj = next;
}
} else {
if (next === undefined || next === null) return false;
obj = next;
}
return false;
};
}
return false;
};
api.common.deleteByPath = (
// Delete property by dot-separated path
data, // object
dataPath // string, dot-separated path
) => {
const path = dataPath.split('.');
let obj = data;
let i, len, next, prop;
for (i = 0, len = path.length; i < len; i++) {
prop = path[i];
next = obj[prop];
if (i === path.length - 1) {
if (obj.hasOwnProperty(prop)) {
delete obj[prop];
return true;
}
} else {
if (next === undefined || next === null) return false;
obj = next;
}
const merge = (
// Distinct merge miltiple arrays
...args // arrays
) => {
const array = args[0];
let i, ilen, j, jlen, arr, val;
for (i = 1, ilen = args.length; i < ilen; i++) {
arr = args[i];
for (j = 0, jlen = arr.length; j < jlen; j++) {
val = arr[j];
if (!array.includes(val)) array.push(val);
}
return false;
};
}
return array;
};
api.common.merge = (
// Distinct merge miltiple arrays
...args // arrays
) => {
const array = args[0];
let i, ilen, j, jlen, arr, val;
for (i = 1, ilen = args.length; i < ilen; i++) {
arr = args[i];
for (j = 0, jlen = arr.length; j < jlen; j++) {
val = arr[j];
if (!array.includes(val)) array.push(val);
}
}
return array;
};
module.exports = {
isScalar,
copy,
clone,
duplucate,
getByPath,
setByPath,
deleteByPath,
merge
};
'use strict';
module.exports = (api) => {
const omap = (
// Function for mapping object fields
mapFn, // funtions applied to every field value
obj // object which fields used for mapping
// Returns object with same reference but with transformed fields
) => {
let key;
for (key in obj) {
obj[key] = mapFn(obj[key]);
}
return obj;
};
api.common.omap = (
// Function for mapping object fields
mapFn, // funtions applied to every field value
obj // object which fields used for mapping
// Returns object with same reference but with transformed fields
) => {
let key;
for (key in obj) {
obj[key] = mapFn(obj[key]);
}
return obj;
};
const compose = (
// Compose functions
...fns // functions
) => (
...args // arguments to bassed to first function
) => {
if (fns.length === 0) return args[0];
api.common.compose = (
// Compose functions
...fns // functions
) => (
...args // arguments to bassed to first function
) => {
if (fns.length === 0) return args[0];
let res = fns[0](...args);
let i;
for (i = 1; i < fns.length; i++) {
res = fns[i](res);
}
return res;
};
let res = fns[0](...args);
let i;
for (i = 1; i < fns.length; i++) {
res = fns[i](res);
}
return res;
};
const maybe = (fn, defVal, value) => (
value !== undefined && value !== null ? fn(value) : defVal
);
api.common.maybe = (fn, defVal, value) => (
value !== undefined && value !== null ? fn(value) : defVal
);
const zip = (
// Zipping several arrays into one
...arrays // input arrays
// Returns array length is minimal of input arrays length
// Element with index i of resulting array is array with
// elements with index i from input arrays
) => {
if (arrays.length === 0) return arrays;
let i, j;
api.common.zip = (
// Zipping several arrays into one
...arrays // input arrays
// Returns array length is minimal of input arrays length
// Element with index i of resulting array is array with
// elements with index i from input arrays
) => {
if (arrays.length === 0) return arrays;
let i, j;
let minLen = arrays[0].length;
for (i = 1; i < arrays.length; i++) {
minLen = Math.min(arrays[i].length, minLen);
}
let minLen = arrays[0].length;
for (i = 1; i < arrays.length; i++) {
minLen = Math.min(arrays[i].length, minLen);
const res = new Array(minLen);
for (i = 0; i < res.length; i++) {
res[i] = new Array(arrays.length);
for (j = 0; j < res[i].length; j++) {
res[i][j] = arrays[j][i];
}
}
return res;
};
const res = new Array(minLen);
for (i = 0; i < res.length; i++) {
res[i] = new Array(arrays.length);
for (j = 0; j < res[i].length; j++) {
res[i][j] = arrays[j][i];
}
}
return res;
};
const replicate = (count, elem) => Array.from(
{ length: count },
() => elem
);
api.common.replicate = (count, elem) => Array.from(
{ length: count },
() => elem
);
const zipWith = (
// Zipping arrays using specific function
fn, // function for zipping elements with index i
...arrays // input arrays
// Element with index i of resulting array is result
// of fn called with arguments from arrays
) => zip(...arrays).map(args => fn(...args));
api.common.zipWith = (
// Zipping arrays using specific function
fn, // function for zipping elements with index i
...arrays // input arrays
// Element with index i of resulting array is result
// of fn called with arguments from arrays
) => (
api.common
.zip(...arrays)
.map(args => fn(...args))
);
api.common.curryUntil = (
// Curries function until the condition
condition, // function(argsI, argsParts) returns boolean
// argsI is arguments for i-th currying
// argsParts is array of args given for currying from first to i-th currying
fn, // function which will be curried
...args // arguments for fn
// Returns curried function
) => {
const argsParts = [];
const curryUntil = (
// Curries function until the condition
condition, // function(argsI, argsParts) returns boolean
// argsI is arguments for i-th currying
// argsParts is array of args given for currying from first to i-th currying
fn, // function which will be curried
...args // arguments for fn
// Returns curried function
) => {
const argsParts = [];
const curryMore = (...argsI) => {
argsParts.push(argsI);
if (condition(argsI, argsParts)) {
const allArgs = [].concat(...argsParts);
return fn(...allArgs);
}
return curryMore;
};
return curryMore(...args);
const curryMore = (...argsI) => {
argsParts.push(argsI);
if (condition(argsI, argsParts)) {
const allArgs = [].concat(...argsParts);
return fn(...allArgs);
}
return curryMore;
};
api.common.curryN = (
// Curry fn count times.
// First curry uses args as arguments for first currying
fn, // curried function
count, // number of times function should be curried
...args // arguments for first currying
// Returns curried count times function
) => {
let i = -1;
const condition = () => (i++, i === count);
return api.common.curryUntil(condition, fn, ...args);
};
return curryMore(...args);
};
api.common.curryTwice = fn => api.common.curry(api.common.curry, fn);
const curry = (
// Curry function
fn, // function
...args // arguments
) => {
let argsTotalCount = 0;
const condition = (argsI) => (
argsTotalCount += argsI.length,
argsTotalCount >= fn.length
);
return curryUntil(condition, fn, ...args);
};
api.common.curry = (
// Curry function
fn, // function
...args // arguments
) => {
let argsTotalCount = 0;
const condition = (argsI) => (
argsTotalCount += argsI.length,
argsTotalCount >= fn.length
);
return api.common.curryUntil(condition, fn, ...args);
};
const curryN = (
// Curry fn count times.
// First curry uses args as arguments for first currying
fn, // curried function
count, // number of times function should be curried
...args // arguments for first currying
// Returns curried count times function
) => {
let i = -1;
const condition = () => (i++, i === count);
return curryUntil(condition, fn, ...args);
};
api.common.applyArgs = (...args) => fn => fn(...args);
const curryTwice = fn => curry(curry, fn);
api.common.either = (
// Return first not errored result of fn
fn // function to be called
) => (
...args // arguments to iterate
) => {
let arg;
let lastError;
for (arg of args) {
try {
return fn(arg);
} catch (error) {
lastError = error;
}
const applyArgs = (...args) => fn => fn(...args);
const either = (
// Return first not errored result of fn
fn // function to be called
) => (
...args // arguments to iterate
) => {
let arg, lastError;
for (arg of args) {
try {
return fn(arg);
} catch (error) {
lastError = error;
}
throw lastError;
};
}
throw lastError;
};
module.exports = {
omap,
compose,
maybe,
zip,
replicate,
zipWith,
curryUntil,
curryN,
curryTwice,
curry,
applyArgs,
either
};
'use strict';
module.exports = (api) => {
const crypto = require('crypto');
api.common.longDivModBE = (
// Divide a long big endian encoded unsigned integer by a small one
// (i.e., not longer than a machine word) in-place and return the remainder
buffer, // Buffer containing a divident
divisor // a divisor as a Number
// Return: the remainder (Number)
) => {
if (divisor === 0) {
throw new Error('Division by zero');
}
const bytesCount = Buffer.byteLength(buffer);
let remainder = 0;
let i, j, resultByte, byte;
for (i = 0; i < bytesCount; i++) {
byte = buffer[i];
resultByte = 0;
for (j = 7; j > -1; j--) {
remainder <<= 1;
resultByte <<= 1;
remainder |= (byte & (1 << j)) >> j;
if (remainder >= divisor) {
remainder -= divisor;
resultByte |= 1;
}
const longDivModBE = (
// Divide a long big endian encoded unsigned integer by a small one
// (i.e., not longer than a machine word) in-place and return the remainder
buffer, // Buffer containing a divident
divisor // a divisor as a Number
// Return: the remainder (Number)
) => {
if (divisor === 0) {
throw new Error('Division by zero');
}
const bytesCount = Buffer.byteLength(buffer);
let remainder = 0;
let i, j, resultByte, byte;
for (i = 0; i < bytesCount; i++) {
byte = buffer[i];
resultByte = 0;
for (j = 7; j > -1; j--) {
remainder <<= 1;
resultByte <<= 1;
remainder |= (byte & (1 << j)) >> j;
if (remainder >= divisor) {
remainder -= divisor;
resultByte |= 1;
}
buffer[i] = resultByte;
}
return remainder;
};
buffer[i] = resultByte;
}
return remainder;
};
api.common.generateKey = (
length, // random key length
possible // string of possible characters
) => {
const base = possible.length;
const bitsCount = Math.ceil(Math.log2(Math.pow(base, length + 1) - 1));
const bytes = api.crypto.randomBytes(Math.ceil(bitsCount / 8));
let key = '';
let i, index;
for (i = 0; i < length; i++) {
index = api.common.longDivModBE(bytes, base);
key += possible[index];
}
return key;
};
const generateKey = (
length, // random key length
possible // string of possible characters
) => {
const base = possible.length;
const bitsCount = Math.ceil(Math.log2(Math.pow(base, length + 1) - 1));
const bytes = crypto.randomBytes(Math.ceil(bitsCount / 8));
let key = '';
let i, index;
for (i = 0; i < length; i++) {
index = longDivModBE(bytes, base);
key += possible[index];
}
return key;
};
api.common.generateGUID = (
// Generate an RFC4122-compliant GUID (UUID v4)
) => {
const bytes = api.crypto.randomBytes(128);
const generateGUID = (
// Generate an RFC4122-compliant GUID (UUID v4)
) => {
const bytes = crypto.randomBytes(128);
bytes[6] &= 0x0F;
bytes[6] |= 0x40;
bytes[8] &= 0x3F;
bytes[8] |= 0x80;
bytes[6] &= 0x0F;
bytes[6] |= 0x40;
bytes[8] &= 0x3F;
bytes[8] |= 0x80;
return [
bytes.toString('hex', 0, 4),
bytes.toString('hex', 4, 6),
bytes.toString('hex', 6, 8),
bytes.toString('hex', 8, 10),
bytes.toString('hex', 10, 16)
].join('-');
};
return [
bytes.toString('hex', 0, 4),
bytes.toString('hex', 4, 6),
bytes.toString('hex', 6, 8),
bytes.toString('hex', 8, 10),
bytes.toString('hex', 10, 16)
].join('-');
};
api.common.generateSID = (
config // { length, characters, secret }
) => {
const key = api.common.generateKey(
config.length - 4,
config.characters
);
return key + api.common.crcSID(config, key);
};
const crcSID = (
config, // { length, characters, secret }
key // key to calculate CRC
) => (
crypto
.createHash('md5')
.update(key + config.secret)
.digest('hex')
.substring(0, 4)
);
api.common.crcSID = (
config, // { length, characters, secret }
key // key to calculate CRC
) => (
api.crypto
.createHash('md5')
.update(key + config.secret)
.digest('hex')
.substring(0, 4)
const generateSID = (
config // { length, characters, secret }
) => {
const key = generateKey(
config.length - 4,
config.characters
);
return key + crcSID(config, key);
};
api.common.validateSID = (
// Validate SID
config, // { length, characters, secret }
sid // session id string
) => {
if (!sid) return false;
const crc = sid.substr(sid.length - 4);
const key = sid.substr(0, sid.length - 4);
return api.common.crcSID(config, key) === crc;
};
const validateSID = (
// Validate SID
config, // { length, characters, secret }
sid // session id string
) => {
if (!sid) return false;
const crc = sid.substr(sid.length - 4);
const key = sid.substr(0, sid.length - 4);
return crcSID(config, key) === crc;
};
const hash = (password, salt) => (
crypto
.createHmac('sha512', salt)
.update(password)
.digest('hex')
);
api.common.hash = (password, salt) => (
api.crypto
.createHmac('sha512', salt)
.update(password)
.digest('hex')
);
const validateHash = (hash, password, salt) => (
hash(password, salt) === hash
);
api.common.validateHash = (hash, password, salt) => (
api.common.hash(password, salt) === hash
);
module.exports = {
longDivModBE,
generateKey,
generateGUID,
generateSID,
crcSID,
validateSID,
hash,
validateHash
};
'use strict';
module.exports = (api) => {
const events = require('events');
api.common.falseness = () => false;
api.common.trueness = () => true;
api.common.emptiness = () => {};
const { either } = require('./functional');
api.common.cb = (
// Wrap callback: call once, not null
callback // function (optional)
// Returns wrapped callback
) => {
let done = false;
const wrap = (...args) => {
if (done) return;
done = true;
callback(...args);
};
return callback ? wrap : api.common.emptiness;
const falseness = () => false;
const trueness = () => true;
const emptiness = () => {};
const cb = (
// Wrap callback: call once, not null
callback // function (optional)
// Returns wrapped callback
) => {
let done = false;
const wrap = (...args) => {
if (done) return;
done = true;
callback(...args);
};
return callback ? wrap : emptiness;
};
api.common.cbExtract = (
// Exctracts callback and wraps it with api.common.cb
// callback is last argument if it's function
// otherwise it's api.common.falseness
args // arguments
// Returns wrapped callback
) => {
const callback = args[args.length - 1];
if (typeof(callback) !== 'function') return api.common.emptiness;
const cbExtract = (
// Exctracts callback and wraps it with common.cb
// callback is last argument if it's function
// otherwise it's common.falseness
args // arguments
// Returns wrapped callback
) => {
const callback = args[args.length - 1];
if (typeof(callback) !== 'function') return emptiness;
args.pop();
return api.common.cb(callback);
};
args.pop();
return cb(callback);
};
api.common.override = (
// Override method: save old to `fn.inherited`
obj, // object containing method to override
fn // function, name will be used to find method
// Previous function will be accessible by obj.fnName.inherited
) => {
fn.inherited = obj[fn.name];
obj[fn.name] = fn;
};
const override = (
// Override method: save old to `fn.inherited`
obj, // object containing method to override
fn // function, name will be used to find method
// Previous function will be accessible by obj.fnName.inherited
) => {
fn.inherited = obj[fn.name];
obj[fn.name] = fn;
};
api.common.range = (
// Generate int array from given range
from, // range start
to // range end
// Example: range(1, 5) = [1, 2, 3, 4, 5]
) => {
if (to < from) return [];
const len = to - from + 1;
const range = new Array(len);
let i;
for (i = from; i <= to; i++) {
range[i - from] = i;
}
return range;
};
const range = (
// Generate int array from given range
from, // range start
to // range end
// Example: range(1, 5) = [1, 2, 3, 4, 5]
) => {
if (to < from) return [];
const len = to - from + 1;
const range = new Array(len);
let i;
for (i = from; i <= to; i++) {
range[i - from] = i;
}
return range;
};
api.common.sequence = (
// Generate int array from sequence syntax
seq, // array
max // optional max
// Examples:
// list: sequence([81, 82, 83]) = [81, 82, 83]
// range from..to: sequence([81,,83]) = [81, 82, 83]
// range from..count: sequence([81, [3]]) = [81, 82, 83]
// range from..max-to: sequence([81, [-2]], 5) = [81, 82, 83]
) => {
const from = seq[0];
let to = seq[1];
let res = seq;
if (Array.isArray(to)) {
const count = to[0] < 0 ? max + to[0] : to[0];
res = api.common.range(from, from + count - 1);
} else if (!to) {
to = seq[2];
res = api.common.range(from, to);
}
return res;
};
const sequence = (
// Generate int array from sequence syntax
seq, // array
max // optional max
// Examples:
// list: sequence([81, 82, 83]) = [81, 82, 83]
// range from..to: sequence([81,,83]) = [81, 82, 83]
// range from..count: sequence([81, [3]]) = [81, 82, 83]
// range from..max-to: sequence([81, [-2]], 5) = [81, 82, 83]
) => {
const from = seq[0];
let to = seq[1];
let res = seq;
if (Array.isArray(to)) {
const count = to[0] < 0 ? max + to[0] : to[0];
res = range(from, from + count - 1);
} else if (!to) {
to = seq[2];
res = range(from, to);
}
return res;
};
api.common.random = (
// Generate random int in given range
min, // range start
max // range end
) => {
if (max === undefined) {
max = min;
min = 0;
}
return min + Math.floor(Math.random() * (max - min + 1));
};
const random = (
// Generate random int in given range
min, // range start
max // range end
) => {
if (max === undefined) {
max = min;
min = 0;
}
return min + Math.floor(Math.random() * (max - min + 1));
};
api.common.shuffle = (
// Shuffle an array
arr // array
) => (
arr.sort(() => Math.random() - 0.5)
);
const shuffle = (
// Shuffle an array
arr // array
) => (
arr.sort(() => Math.random() - 0.5)
);
api.common.eventEmitter = (
// EventEmitter with wildcard
) => {
const ee = new api.events.EventEmitter();
const emit = ee.emit;
ee.emit = (...args) => {
const ar = args.slice(0);
ar.unshift('*');
emit.apply(ee, ar);
emit.apply(ee, args);
};
return ee;
const eventEmitter = (
// EventEmitter with wildcard
) => {
const ee = new events.EventEmitter();
const emit = ee.emit;
ee.emit = (...args) => {
const ar = args.slice(0);
ar.unshift('*');
emit.apply(ee, ar);
emit.apply(ee, args);
};
return ee;
};
api.common.restLeft = (
// Rest left, transfor function
fn // (args, arg1..argN, callback) to (arg1..argN, ...args, callback)
) => (...spreadArgs) => {
const callback = api.common.cbExtract(spreadArgs);
const namedArgsCount = fn.length - 2;
const namedArgs = spreadArgs.slice(0, namedArgsCount);
const args = spreadArgs.slice(namedArgsCount);
fn(args, ...namedArgs, callback);
};
const restLeft = (
// Rest left, transfor function
fn // (args, arg1..argN, callback) to (arg1..argN, ...args, callback)
) => (...spreadArgs) => {
const callback = cbExtract(spreadArgs);
const namedArgsCount = fn.length - 2;
const namedArgs = spreadArgs.slice(0, namedArgsCount);
const args = spreadArgs.slice(namedArgsCount);
fn(args, ...namedArgs, callback);
};
api.common.requireEither = api.common.either(require);
const requireEither = either(require);
module.exports = {
falseness,
trueness,
emptiness,
cb,
cbExtract,
override,
range,
sequence,
random,
shuffle,
eventEmitter,
restLeft,
requireEither
};
'use strict';
module.exports = (api) => {
const os = require('os');
api.common.ip2int = (
// Pack IP string to single int
ip = '127.0.0.1'
) => (
ip.split('.').reduce((res, item) => (res << 8) + (+item), 0)
);
const ip2int = (
// Pack IP string to single int
ip = '127.0.0.1'
) => (
ip.split('.').reduce((res, item) => (res << 8) + (+item), 0)
);
api.common.localIPs = (
// Get local network interfaces
// Returns array of strings
) => {
let ips = api.common.localIPs.cache;
if (ips) return ips;
ips = [];
let protocol, ifName, ifItem, i, len;
const ifHash = api.os.networkInterfaces();
for (ifName in ifHash) {
ifItem = ifHash[ifName];
for (i = 0, len = ifItem.length; i < len; i++) {
protocol = ifItem[i];
if (protocol.family === 'IPv4') {
ips.push(protocol.address);
}
let LOCAL_IPS_CACHE;
const localIPs = (
// Get local network interfaces
// Returns array of strings
) => {
if (LOCAL_IPS_CACHE) return LOCAL_IPS_CACHE;
const ips = [];
let protocol, ifName, ifItem, i, len;
const ifHash = os.networkInterfaces();
for (ifName in ifHash) {
ifItem = ifHash[ifName];
for (i = 0, len = ifItem.length; i < len; i++) {
protocol = ifItem[i];
if (protocol.family === 'IPv4') {
ips.push(protocol.address);
}
}
api.common.localIPs.cache = ips;
return ips;
};
}
LOCAL_IPS_CACHE = ips;
return ips;
};
api.common.parseHost = (
// Parse host string
host // host or empty string, may contain :port
// Returns host without port but not empty
) => {
if (!host) host = 'no-host-name-in-http-headers';
const portOffset = host.indexOf(':');
if (portOffset > -1) host = host.substr(0, portOffset);
return host;
};
const parseHost = (
// Parse host string
host // host or empty string, may contain :port
// Returns host without port but not empty
) => {
if (!host) host = 'no-host-name-in-http-headers';
const portOffset = host.indexOf(':');
if (portOffset > -1) host = host.substr(0, portOffset);
return host;
};
module.exports = {
ip2int,
localIPs,
parseHost
};
'use strict';
module.exports = (api) => {
const sortComparePriority = (
// Compare for array.sort with priority
priority, // array of strings with priority
s1, s2 // comparing strings
// Example:
// comp = sortComparePriority(impress.CONFIG_FILES_PRIORITY);
// files.sort(comp);
) => {
let a = priority.indexOf(s1);
let b = priority.indexOf(s2);
if (a === -1) a = Infinity;
if (b === -1) b = Infinity;
if (a < b) return -1;
if (a > b) return 1;
return 0;
};
api.common.sortComparePriority = (
// Compare for array.sort with priority
priority, // array of strings with priority
s1, s2 // comparing strings
// Example:
// comp = api.common.sortComparePriority(impress.CONFIG_FILES_PRIORITY);
// files.sort(comp);
) => {
let a = priority.indexOf(s1);
let b = priority.indexOf(s2);
if (a === -1) a = Infinity;
if (b === -1) b = Infinity;
if (a < b) return -1;
if (a > b) return 1;
return 0;
};
const sortCompareDirectories = (
// Compare for array.sort, directories first
a, b // comparing strings
// Example: files.sort(sortCompareDirectories);
) => {
let s1 = a.name;
let s2 = b.name;
if (s1.charAt(0) !== '/') s1 = '0' + s1;
if (s2.charAt(0) !== '/') s2 = '0' + s2;
if (s1 < s2) return -1;
if (s1 > s2) return 1;
return 0;
};
api.common.sortCompareDirectories = (
// Compare for array.sort, directories first
a, b // comparing strings
// Example: files.sort(api.common.sortCompareDirectories);
) => {
let s1 = a.name;
let s2 = b.name;
if (s1.charAt(0) !== '/') s1 = '0' + s1;
if (s2.charAt(0) !== '/') s2 = '0' + s2;
if (s1 < s2) return -1;
if (s1 > s2) return 1;
return 0;
};
const sortCompareByName = (
// Compare for array.sort
a, b // objects `{ name }` to compare
// Example: files.sort(sortCompareByName);
) => {
const s1 = a.name;
const s2 = b.name;
if (s1 < s2) return -1;
if (s1 > s2) return 1;
return 0;
};
api.common.sortCompareByName = (
// Compare for array.sort
a, b // objects `{ name }` to compare
// Example: files.sort(api.common.sortCompareByName);
) => {
const s1 = a.name;
const s2 = b.name;
if (s1 < s2) return -1;
if (s1 > s2) return 1;
return 0;
};
module.exports = {
sortComparePriority,
sortCompareDirectories,
sortCompareByName
};
'use strict';
module.exports = (api) => {
const path = require('path');
const SUBST_REGEXP = /@([-.0-9a-zA-Z]+)@/g;
const { getByPath } = require('./data');
const { nowDateTime } = require('./time');
api.common.subst = (
// Substitute variables
tpl, // template body
data, // global data structure to visualize
dataPath, // current position in data structure
escapeHtml // escape html special characters if true
// Returns string
) => (
tpl.replace(SUBST_REGEXP, (s, key) => {
const pos = key.indexOf('.');
const name = pos === 0 ? dataPath + key : key;
let value = api.common.getByPath(data, name);
if (value === undefined) {
if (key === '.value') {
value = api.common.getByPath(data, dataPath);
} else {
value = '[undefined]';
}
}
if (value === null) {
value = '[null]';
} else if (value === undefined) {
const HTML_ESCAPE_REGEXP = new RegExp('[&<>"\'/]', 'g');
const HTML_ESCAPE_CHARS = {
'&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', '\'': '&#39;'
};
const htmlEscape = (
// Escape html characters
content // string to escape
// Example: htmlEscape('5>=5') : '5&lt;=5'
) => (
content.replace(HTML_ESCAPE_REGEXP, char => HTML_ESCAPE_CHARS[char])
);
const SUBST_REGEXP = /@([-.0-9a-zA-Z]+)@/g;
const subst = (
// Substitute variables
tpl, // template body
data, // global data structure to visualize
dataPath, // current position in data structure
escapeHtml // escape html special characters if true
// Returns string
) => (
tpl.replace(SUBST_REGEXP, (s, key) => {
const pos = key.indexOf('.');
const name = pos === 0 ? dataPath + key : key;
let value = getByPath(data, name);
if (value === undefined) {
if (key === '.value') {
value = getByPath(data, dataPath);
} else {
value = '[undefined]';
} else if (typeof(value) === 'object') {
if (value.constructor.name === 'Date') {
value = api.common.nowDateTime(value);
} else if (value.constructor.name === 'Array') {
value = '[array]';
} else {
value = '[object]';
}
}
if (escapeHtml) value = api.common.htmlEscape(value);
return value;
})
);
}
if (value === null) {
value = '[null]';
} else if (value === undefined) {
value = '[undefined]';
} else if (typeof(value) === 'object') {
if (value.constructor.name === 'Date') {
value = nowDateTime(value);
} else if (value.constructor.name === 'Array') {
value = '[array]';
} else {
value = '[object]';
}
}
if (escapeHtml) value = htmlEscape(value);
return value;
})
);
const HTML_ESCAPE_REGEXP = new RegExp('[&<>"\'/]', 'g');
const HTML_ESCAPE_CHARS = {
'&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', '\'': '&#39;'
};
const fileExt = (
// Extract file extension in lower case with no dot
fileName // string, file name
// Example: fileExt('/dir/file.txt')
// Result: 'txt'
) => (
path.extname(fileName).replace('.', '').toLowerCase()
);
api.common.htmlEscape = (
// Escape html characters
content // string to escape
// Example: api.common.htmlEscape('5>=5') : '5&lt;=5'
) => (
content.replace(HTML_ESCAPE_REGEXP, char => HTML_ESCAPE_CHARS[char])
);
const removeExt = (
// Remove file extension from file name
fileName // string, file name
// Example: fileExt('file.txt')
// Result: 'file'
) => (
fileName.substr(0, fileName.lastIndexOf('.'))
);
api.common.fileExt = (
// Extract file extension in lower case with no dot
fileName // string, file name
// Example: api.common.fileExt('/dir/file.txt')
// Result: 'txt'
) => (
api.path.extname(fileName).replace('.', '').toLowerCase()
);
const CAPITALIZE_REGEXP = /\w+/g;
api.common.removeExt = (
// Remove file extension from file name
fileName // string, file name
// Example: api.common.fileExt('file.txt')
// Result: 'file'
) => (
fileName.substr(0, fileName.lastIndexOf('.'))
);
const capitalize = (
// Capitalize string
s // string
) => (
s.replace(CAPITALIZE_REGEXP, (word) => (
word.charAt(0).toUpperCase() + word.substr(1).toLowerCase()
))
);
const UNDERLINE_REGEXP = /_/g;
const UNDERLINE_REGEXP = /_/g;
api.common.spinalToCamel = (
// convert spinal case to camel case
name // string
) => (
name
.replace(UNDERLINE_REGEXP, '-')
.split('-')
.map((part, i) => (i > 0 ? api.common.capitalize(part) : part))
.join('')
);
const spinalToCamel = (
// convert spinal case to camel case
name // string
) => (
name
.replace(UNDERLINE_REGEXP, '-')
.split('-')
.map((part, i) => (i > 0 ? capitalize(part) : part))
.join('')
);
const ESCAPE_REGEXP_SPECIALS = [
// order matters for these
'-', '[', ']',
// order doesn't matter for any of these
'/', '{', '}', '(', ')', '*', '+', '?', '.', '\\', '^', '$', '|'
];
const ESCAPE_REGEXP_SPECIALS = [
// order matters for these
'-', '[', ']',
// order doesn't matter for any of these
'/', '{', '}', '(', ')', '*', '+', '?', '.', '\\', '^', '$', '|'
];
const ESCAPE_REGEXP = new RegExp(
'[' + ESCAPE_REGEXP_SPECIALS.join('\\') + ']', 'g'
);
const ESCAPE_REGEXP = new RegExp(
'[' + ESCAPE_REGEXP_SPECIALS.join('\\') + ']', 'g'
);
api.common.escapeRegExp = (
// Escape regular expression control characters
s // string
// Example: escapeRegExp('/path/to/res?search=this.that')
) => (
s.replace(ESCAPE_REGEXP, '\\$&')
);
const escapeRegExp = (
// Escape regular expression control characters
s // string
// Example: escapeRegExp('/path/to/res?search=this.that')
) => (
s.replace(ESCAPE_REGEXP, '\\$&')
);
api.common.newEscapedRegExp = (
// Generate escaped regular expression
s // string
// Returns: instance of RegExp
) => (
new RegExp(api.common.escapeRegExp(s), 'g')
);
const newEscapedRegExp = (
// Generate escaped regular expression
s // string
// Returns: instance of RegExp
) => (
new RegExp(escapeRegExp(s), 'g')
);
api.common.addTrailingSlash = (s) => s + (s.endsWith('/') ? '' : '/');
const addTrailingSlash = (s) => s + (s.endsWith('/') ? '' : '/');
api.common.stripTrailingSlash = (
// Remove trailing slash from string
s // string
) => (
s.endsWith('/') ? s.substr(0, s.length - 1) : s
);
const stripTrailingSlash = (
// Remove trailing slash from string
s // string
) => (
s.endsWith('/') ? s.substr(0, s.length - 1) : s
);
api.common.dirname = (
// Get directory name with trailing slash from path
path // string
) => {
let dir = api.path.dirname(path);
if (dir !== '/') dir += '/';
return dir;
};
const dirname = (
// Get directory name with trailing slash from path
path // string
) => {
let dir = path.dirname(path);
if (dir !== '/') dir += '/';
return dir;
};
const CAPITALIZE_REGEXP = /\w+/g;
const between = (
// Extract substring between prefix and suffix
s, // source string
prefix, // substring before needed fragment
suffix // substring after needed fragment
) => {
let i = s.indexOf(prefix);
if (i === -1) return '';
s = s.substring(i + prefix.length);
if (suffix) {
i = s.indexOf(suffix);
if (i === -1) return '';
s = s.substring(0, i);
}
return s;
};
api.common.capitalize = (
// Capitalize string
s // string
) => (
s.replace(CAPITALIZE_REGEXP, (word) => (
word.charAt(0).toUpperCase() + word.substr(1).toLowerCase()
))
);
const BOM_REGEXP = /^[\uBBBF\uFEFF]*/;
api.common.between = (
// Extract substring between prefix and suffix
s, // source string
prefix, // substring before needed fragment
suffix // substring after needed fragment
) => {
let i = s.indexOf(prefix);
if (i === -1) return '';
s = s.substring(i + prefix.length);
if (suffix) {
i = s.indexOf(suffix);
if (i === -1) return '';
s = s.substring(0, i);
}
return s;
};
const removeBOM = (
// Remove UTF-8 BOM
s // string possibly starts with BOM
) => (
typeof(s) === 'string' ? s.replace(BOM_REGEXP, '') : s
);
const BOM_REGEXP = /^[\uBBBF\uFEFF]*/;
const ITEM_ESCAPE_REGEXP = /\\\*/g;
api.common.removeBOM = (
// Remove UTF-8 BOM
s // string possibly starts with BOM
) => (
typeof(s) === 'string' ? s.replace(BOM_REGEXP, '') : s
const arrayRegExp = (
// Generate RegExp from array with '*' wildcards
items // array of strings
// Example: ['/css/*', '/index.html']
) => {
if (!items || items.length === 0) return null;
items = items.map(
item => escapeRegExp(item).replace(ITEM_ESCAPE_REGEXP, '.*')
);
const ex = items.length === 1 ? items[0] : '((' + items.join(')|(') + '))';
return new RegExp('^' + ex + '$');
};
const ITEM_ESCAPE_REGEXP = /\\\*/g;
api.common.arrayRegExp = (
// Generate RegExp from array with '*' wildcards
items // array of strings
// Example: ['/css/*', '/index.html']
) => {
if (!items || items.length === 0) return null;
items = items.map(
item => api.common.escapeRegExp(item).replace(ITEM_ESCAPE_REGEXP, '.*')
);
const ex = items.length === 1 ? items[0] : '((' + items.join(')|(') + '))';
return new RegExp('^' + ex + '$');
};
module.exports = {
subst,
htmlEscape,
fileExt,
removeExt,
spinalToCamel,
escapeRegExp,
newEscapedRegExp,
addTrailingSlash,
stripTrailingSlash,
dirname,
capitalize,
between,
removeBOM,
arrayRegExp
};
'use strict';
module.exports = (api) => {
const isTimeEqual = (
// Compare time1 and time2
time1, // time string or milliseconds
time2 // time string or milliseconds
// Example: isTimeEqual(sinceTime, buffer.stats.mtime);
// Result: boolean
) => (
new Date(time1).getTime() === new Date(time2).getTime()
);
api.common.isTimeEqual = (
// Compare time1 and time2
time1, // time string or milliseconds
time2 // time string or milliseconds
// Example: api.common.isTimeEqual(sinceTime, buffer.stats.mtime);
// Result: boolean
) => (
new Date(time1).getTime() === new Date(time2).getTime()
const pad2 = n => (n < 10 ? '0' + n : '' + n);
const nowDate = (
// Current date in YYYY-MM-DD format
now // date object (optional)
// Returns string
) => {
if (!now) now = new Date();
return (
now.getUTCFullYear() + '-' +
pad2(now.getUTCMonth() + 1) + '-' +
pad2(now.getUTCDate())
);
};
const pad2 = n => (n < 10 ? '0' + n : '' + n);
const nowDateTime = (
// Current date in YYYY-MM-DD hh:mm format
now // date object (optional)
// Returns string
) => {
if (!now) now = new Date();
return (
now.getUTCFullYear() + '-' +
pad2(now.getUTCMonth() + 1) + '-' +
pad2(now.getUTCDate()) + ' ' +
pad2(now.getUTCHours()) + ':' +
pad2(now.getUTCMinutes())
);
};
api.common.nowDate = (
// Current date in YYYY-MM-DD format
now // date object (optional)
// Returns string
) => {
if (!now) now = new Date();
return (
now.getUTCFullYear() + '-' +
pad2(now.getUTCMonth() + 1) + '-' +
pad2(now.getUTCDate())
);
};
api.common.nowDateTime = (
// Current date in YYYY-MM-DD hh:mm format
now // date object (optional)
// Returns string
) => {
if (!now) now = new Date();
return (
now.getUTCFullYear() + '-' +
pad2(now.getUTCMonth() + 1) + '-' +
pad2(now.getUTCDate()) + ' ' +
pad2(now.getUTCHours()) + ':' +
pad2(now.getUTCMinutes())
);
};
module.exports = {
isTimeEqual,
pad2,
nowDate,
nowDateTime
};
'use strict';
module.exports = (api) => {
const DURATION_UNITS = {
days: { rx: /(\d+)\s*d/, mul: 86400 },
hours: { rx: /(\d+)\s*h/, mul: 3600 },
minutes: { rx: /(\d+)\s*m/, mul: 60 },
seconds: { rx: /(\d+)\s*s/, mul: 1 }
};
const DURATION_UNITS = {
days: { rx: /(\d+)\s*d/, mul: 86400 },
hours: { rx: /(\d+)\s*h/, mul: 3600 },
minutes: { rx: /(\d+)\s*m/, mul: 60 },
seconds: { rx: /(\d+)\s*s/, mul: 1 }
};
api.common.duration = (
// Parse duration to seconds
s // string in duration syntax
// Example: duration('1d 10h 7m 13s')
// Returns milliseconds
) => {
if (typeof(s) === 'number') return s;
let result = 0;
let unit, match, key;
if (typeof(s) === 'string') {
for (key in DURATION_UNITS) {
unit = DURATION_UNITS[key];
match = s.match(unit.rx);
if (match) result += parseInt(match[1], 10) * unit.mul;
}
const duration = (
// Parse duration to seconds
s // string in duration syntax
// Example: duration('1d 10h 7m 13s')
// Returns milliseconds
) => {
if (typeof(s) === 'number') return s;
let result = 0;
let unit, match, key;
if (typeof(s) === 'string') {
for (key in DURATION_UNITS) {
unit = DURATION_UNITS[key];
match = s.match(unit.rx);
if (match) result += parseInt(match[1], 10) * unit.mul;
}
return result * 1000;
};
}
return result * 1000;
};
api.common.bytesToSize = (
// Convert int to string size Kb, Mb, Gb and Tb
bytes // int size
) => {
if (bytes === 0) return '0';
const i = parseInt(Math.floor(Math.log(bytes) / Math.log(1000)), 10);
return (
Math.round(bytes / Math.pow(1000, i), 2) +
api.common.bytesToSize.sizes[i]
);
};
const SIZE_UNITS = [
'', ' Kb', ' Mb', ' Gb', ' Tb', ' Pb', ' Eb', ' Zb', ' Yb'
];
api.common.bytesToSize.sizes = [
'', ' Kb', ' Mb', ' Gb', ' Tb', ' Pb', ' Eb', ' Zb', ' Yb'
];
const bytesToSize = (
// Convert int to string size Kb, Mb, Gb and Tb
bytes // int size
) => {
if (bytes === 0) return '0';
const i = parseInt(Math.floor(Math.log(bytes) / Math.log(1000)), 10);
return Math.round(bytes / Math.pow(1000, i), 2) + SIZE_UNITS[i];
};
api.common.sizeToBytes = (
// Convert string with units to int
size // string size
) => {
if (typeof(size) === 'number') return size;
size = size.toUpperCase();
let result = 0;
const units = api.common.sizeToBytes.units;
if (typeof(size) === 'string') {
let key, unit, match;
let found = false;
for (key in units) {
unit = units[key];
match = size.match(unit.rx);
if (match) {
result += parseInt(match[1], 10) * Math.pow(10, unit.pow);
found = true;
}
const UNIT_SIZES = {
yb: { rx: /(\d+)\s*YB/, pow: 24 },
zb: { rx: /(\d+)\s*ZB/, pow: 21 },
eb: { rx: /(\d+)\s*EB/, pow: 18 },
pb: { rx: /(\d+)\s*PB/, pow: 15 },
tb: { rx: /(\d+)\s*TB/, pow: 12 },
gb: { rx: /(\d+)\s*GB/, pow: 9 },
mb: { rx: /(\d+)\s*MB/, pow: 6 },
kb: { rx: /(\d+)\s*KB/, pow: 3 }
};
const sizeToBytes = (
// Convert string with units to int
size // string size
) => {
if (typeof(size) === 'number') return size;
size = size.toUpperCase();
let result = 0;
if (typeof(size) === 'string') {
let key, unit, match;
let found = false;
for (key in UNIT_SIZES) {
unit = UNIT_SIZES[key];
match = size.match(unit.rx);
if (match) {
result += parseInt(match[1], 10) * Math.pow(10, unit.pow);
found = true;
}
if (!found) result = parseInt(size, 10);
}
return result;
};
if (!found) result = parseInt(size, 10);
}
return result;
};
api.common.sizeToBytes.units = {
yb: { rx: /(\d+)\s*YB/, pow: 24 },
zb: { rx: /(\d+)\s*ZB/, pow: 21 },
eb: { rx: /(\d+)\s*EB/, pow: 18 },
pb: { rx: /(\d+)\s*PB/, pow: 15 },
tb: { rx: /(\d+)\s*TB/, pow: 12 },
gb: { rx: /(\d+)\s*GB/, pow: 9 },
mb: { rx: /(\d+)\s*MB/, pow: 6 },
kb: { rx: /(\d+)\s*KB/, pow: 3 }
};
module.exports = {
duration,
bytesToSize,
sizeToBytes
};
{
"name": "metarhia-common",
"version": "0.0.12",
"version": "0.0.13",
"author": "Timur Shemsedinov <timur.shemsedinov@gmail.com>",

@@ -17,3 +17,3 @@ "description": "Metarhia Common Library",

"type": "git",
"url": "https://github.com/metarhia/Common"
"url": "https://github.com/metarhia/common"
},

@@ -23,3 +23,3 @@ "main": "./common.js",

"scripts": {
"test": "tap test/*.js && npm run lint",
"test": "eslint . && tap test/*.js",
"code-coverage": "tap test/*.js --100",

@@ -34,12 +34,4 @@ "code-coverage-report": "tap test/*.js --coverage-report=html",

"eslint": "^4.1.1",
"eslint-plugin-metarhia": "0.0.2",
"tap": "^10.7.0"
},
"jshintConfig": {
"esversion": 6,
"predef": [],
"node": true,
"indent": 2,
"maxcomplexity": 7
}
}

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc