Comparing version 0.0.0 to 3.0.0
186
metautil.js
'use strict'; | ||
module.exports = {}; | ||
const path = require('path'); | ||
const crypto = require('crypto'); | ||
class CryptoRandomPrefetcher { | ||
constructor(bufSize, valueSize) { | ||
if (bufSize % valueSize !== 0) { | ||
throw new RangeError('buffer size must be a multiple of value size'); | ||
} | ||
this.buf = crypto.randomBytes(bufSize); | ||
this.pos = 0; | ||
this.vsz = valueSize; | ||
} | ||
// Return Buffer with next `valueSize` random bytes. | ||
next() { | ||
if (this.pos === this.buf.length) { | ||
this.pos = 0; | ||
crypto.randomFillSync(this.buf); | ||
} | ||
const end = this.pos + this.vsz; | ||
const buf = this.buf.slice(this.pos, end); | ||
this.pos = end; | ||
return buf; | ||
} | ||
[Symbol.iterator]() { | ||
return { | ||
[Symbol.iterator]() { | ||
return this; | ||
}, | ||
next: () => ({ value: this.next(), done: false }), | ||
}; | ||
} | ||
} | ||
const cryptoPrefetcher = (bufSize, valueSize) => | ||
new CryptoRandomPrefetcher(bufSize, valueSize); | ||
const random = (min, max) => { | ||
if (max === undefined) { | ||
max = min; | ||
min = 0; | ||
} | ||
return min + Math.floor(Math.random() * (max - min + 1)); | ||
}; | ||
const randPrefetcher = cryptoPrefetcher(4096, 4); | ||
const UINT32_MAX = 0xffffffff; | ||
const cryptoRandom = () => | ||
randPrefetcher.next().readUInt32LE(0, true) / (UINT32_MAX + 1); | ||
const sample = (arr) => { | ||
const index = Math.floor(Math.random() * arr.length); | ||
return arr[index]; | ||
}; | ||
const ipToInt = (ip = '127.0.0.1') => { | ||
if (ip === '') return 0; | ||
const bytes = ip.split('.'); | ||
let res = 0; | ||
for (const byte of bytes) { | ||
res = (res << 8) + parseInt(byte, 10); | ||
} | ||
return res; | ||
}; | ||
const parseHost = (host) => { | ||
if (!host) { | ||
return 'no-host-name-in-http-headers'; | ||
} | ||
const portOffset = host.indexOf(':'); | ||
if (portOffset > -1) host = host.substr(0, portOffset); | ||
return host; | ||
}; | ||
const replace = (str, substr, newstr) => { | ||
if (substr === '') return str; | ||
let src = str; | ||
let res = ''; | ||
do { | ||
const index = src.indexOf(substr); | ||
if (index === -1) return res + src; | ||
const start = src.substring(0, index); | ||
src = src.substring(index + substr.length, src.length); | ||
res += start + newstr; | ||
} while (true); | ||
}; | ||
const fileExt = (fileName) => { | ||
const ext = path.extname(fileName).toLowerCase(); | ||
return replace(ext, '.', ''); | ||
}; | ||
const between = (s, prefix, suffix) => { | ||
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 twoDigit = (n) => { | ||
const s = n.toString(); | ||
if (n < 10) return '0' + s; | ||
return s; | ||
}; | ||
const nowDate = (date) => { | ||
if (!date) date = new Date(); | ||
const yyyy = date.getUTCFullYear().toString(); | ||
const mm = twoDigit(date.getUTCMonth() + 1); | ||
const dd = twoDigit(date.getUTCDate()); | ||
return `${yyyy}-${mm}-${dd}`; | ||
}; | ||
const DURATION_UNITS = { | ||
d: 86400, // days | ||
h: 3600, // hours | ||
m: 60, // minutes | ||
s: 1, // seconds | ||
}; | ||
const duration = (s) => { | ||
if (typeof s === 'number') return s; | ||
if (typeof s !== 'string') return 0; | ||
let result = 0; | ||
const parts = s.split(' '); | ||
for (const part of parts) { | ||
const unit = part.slice(-1); | ||
const value = parseInt(part.slice(0, -1)); | ||
const mult = DURATION_UNITS[unit]; | ||
if (!isNaN(value) && mult) result += value * mult; | ||
} | ||
return result * 1000; | ||
}; | ||
const generateKey = (length, possible) => { | ||
const base = possible.length; | ||
let key = ''; | ||
for (let i = 0; i < length; i++) { | ||
const index = Math.floor(cryptoRandom() * base); | ||
key += possible[index]; | ||
} | ||
return key; | ||
}; | ||
const crcToken = (secret, key) => { | ||
const md5 = crypto.createHash('md5').update(key + secret); | ||
return md5.digest('hex').substring(0, 4); | ||
}; | ||
const generateToken = (secret, characters, length) => { | ||
const key = generateKey(length - 4, characters); | ||
return key + crcToken(secret, key); | ||
}; | ||
const validateToken = (secret, token) => { | ||
if (!token) return false; | ||
const len = token.length; | ||
const crc = token.slice(len - 4); | ||
const key = token.slice(0, -4); | ||
return crcToken(secret, key) === crc; | ||
}; | ||
module.exports = { | ||
sample, | ||
ipToInt, | ||
parseHost, | ||
replace, | ||
fileExt, | ||
between, | ||
nowDate, | ||
duration, | ||
generateKey, | ||
generateToken, | ||
crcToken, | ||
validateToken, | ||
random, | ||
cryptoRandom, | ||
}; |
{ | ||
"name": "metautil", | ||
"version": "0.0.0", | ||
"version": "3.0.0", | ||
"author": "Timur Shemsedinov <timur.shemsedinov@gmail.com>", | ||
@@ -26,4 +26,4 @@ "license": "MIT", | ||
"scripts": { | ||
"lint": "eslint . && prettier --check \"**/*.js\" \"**/*.json\" \"**/*.md\" \"**/.*rc\" \"**/*.yml\"", | ||
"fmt": "prettier --write \"**/*.js\" \"**/*.json\" \"**/*.md\" \"**/.*rc\" \"**/*.yml\"", | ||
"lint": "eslint . && prettier --check \"**/*.js\" \"**/*.json\" \"**/*.md\" \"**/.*rc\"", | ||
"fmt": "prettier --write \"**/*.js\" \"**/*.json\" \"**/*.md\" \"**/.*rc\"", | ||
"test": "eslint . && metatests test/" | ||
@@ -30,0 +30,0 @@ }, |
# Metarhia utilities | ||
[![CI Status](https://github.com/metarhia/metautil/workflows/Testing%20CI/badge.svg)](https://github.com/metarhia/metautil/actions?query=workflow%3A%22Testing+CI%22+branch%3Amaster) | ||
[![NPM Version](https://badge.fury.io/js/metautil.svg)](https://badge.fury.io/js/metautil) | ||
[![NPM Downloads/Month](https://img.shields.io/npm/dm/metautil.svg)](https://www.npmjs.com/package/metautil) | ||
[![NPM Downloads](https://img.shields.io/npm/dt/metautil.svg)](https://www.npmjs.com/package/metautil) | ||
[![ci status](https://github.com/metarhia/metautil/workflows/Testing%20CI/badge.svg)](https://github.com/metarhia/metautil/actions?query=workflow%3A%22Testing+CI%22+branch%3Amaster) | ||
[![snyk](https://snyk.io/test/github/metarhia/metautil/badge.svg)](https://snyk.io/test/github/metarhia/metautil) | ||
[![npm version](https://badge.fury.io/js/metautil.svg)](https://badge.fury.io/js/metautil) | ||
[![npm downloads/month](https://img.shields.io/npm/dm/metautil.svg)](https://www.npmjs.com/package/metautil) | ||
[![npm downloads](https://img.shields.io/npm/dt/metautil.svg)](https://www.npmjs.com/package/metautil) | ||
[![license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/metarhia/metautil/blob/master/LICENSE) | ||
## Contributors | ||
See github for full [contributors list](https://github.com/metarhia/metautil/graphs/contributors) |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Trivial Package
Supply chain riskPackages less than 10 lines of code are easily copied into your own project and may not warrant the additional supply chain risk of an external dependency.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
7772
5
164
0
13
0