
Research
Two Malicious Rust Crates Impersonate Popular Logger to Steal Wallet Keys
Socket uncovers malicious Rust crates impersonating fast_log to steal Solana and Ethereum wallet keys from source code.
mad-utils
Advanced tools
A set of misc utilties I find myself repeatedly re-writing between projects.
Collection of utilities I keep repeatedly rewriting across projects.
(see full docs in lower sections for more details)
Capitalize first letter, convert rest to lowercase.
cap1LowerRest('aSdF'); // => 'Asdf'
Capitalize first letter. Leave the rest as-is.
capitalize('asdf'); // => 'Asdf'
capitalize('asDf'); // => 'AsDf'
eliminateWhitespace(' asdf 123 ff '); // => 'asdf123ff'
Function-based switch statement. Takes 2 or more args.
Examples:
switchExpr(true, 'val1'); // Output: 'val1'
switchExpr(false, 'val1', 'defaultVal'); // Output: 'defaultVal'
switchExpr(
false, 'v1',
true, 'v2',
'defaultReturnVal'); // Output: 'v2'
switchExpr(undefined, 'v1', '', 'v2'); // Throws Error
first([1,2,3]); => 1
last([1,2,3]); => 3
Search array for value. Returns true if array contains value. Uses simple JSON.stringify for comparison.
matchAny([1, 2, 3])(2);
// => true
matchAny(['a', 6, [1, 2, 3], 'gr'])([1, 2, 3]);
// => true
uuid(); // => 5A42CCCF-6B10-488B-B957-4D1E5A113DA4
uuid(); // => 38259F99-73D5-4EE1-B11F-5D33CE8AD2C6
Safely get the item at the given object path.
const obj = {a: {b: {c: 'value'}}};
get(obj, 'a.b.c'); // => 'value'
get(obj, 'a.b.zzz', 'default value'); // => 'default value'
isBoolean(true); // => true
isBoolean(false); // => true
isBoolean({}); // => false
isFalse(true); // => false
isFalse(false); // => true
isFalse('ok'); // => false
isInt(5); // => true
isInt(-10); // => true
isInt(1.6); // => false
isInt('okok'); // => false
const arr = [1, 2, 3]
pushIfNew(3); // => [1, 2, 3]
pushIfNew(4); // => [1, 2, 3, 4]
console.log(arr); // => [1, 2, 3, 4]
repeatChars('a', 5); // => 'aaaaa'
repeatChars('aa', 5); // => 'aaaaaaaaaa'
Signature:
<T = ('en' | 'fr')>(
string? = location.pathname,
T[]? = ['en', 'fr']
T? = 'en'
) => string
TODO confirm getLangFromURLPathname signature
Example usage:
// With URL http://example.com/auth/fr/ok:
getLangFromURLPathname(); // => 'fr'
// With URL http://example.com/en/auth/ok:
getLangFromURLPathname(); // => 'en'
// With URL given as param:
getLangFromURLPathname(`http://example.com/auth/sp/ok`, [`en`, `fr`, `sp`]); // => 'sp'
// With URL http://example.com/home?hello=everyone&gr=argh:
parseQueryParams(); // => { hello: 'everyone', gr: 'argh' }
npm install --save mad-utils
yarn add mad-utils
// Import all namespaces, functions, types, etc. from isomorphic submodule
import {m_} from 'mad-utils';
// Import isomorphic namespaces
import {array, json, enum, number, object, query, string, types} from 'mad-utils';
// Import individual isomorphic functions, types, classes, etc.
import {first, isNumberLike, parseQueryParams, castToNum, stringToEnumVal} from 'mad-utils';
All of the above namespaces are also importable from the NodeJS and Browser modules.
Isomorphic exports, plus exports that will only work in a Node environment, such as:
Will generally crash your application if imported into the browser.
// Import all namespaces, functions, types, etc. from node & isomorphic submodules
import {m_} from 'mad-utils/lib/node';
// Import node (and isomorphic) namespaces
import {file, test, middleware, webpackUtils, nodeError, date} from 'mad-utils/lib/node';
// Import individual node (and isomorphic) functions, types, classes, etc.
import {
isDir,
wasRunAsScript,
replaceInFile,
getJsFilesInDir,
globalActivateCleanStack,
useMiddlewareInProductionOnly,
third,
thirdLast,
splitLines,
composeExpressMiddlewares,
isNonMinFile,
eliminateWhitespace
} from 'mad-utils/lib/node';
// Import all namespaces, functions, types, etc. from browser submodule
import {m_} from 'mad-utils/lib/browser';
// Import namespaces from browser (and isomorphic) submodules
import {dom, types} from 'mad-utils/lib/node';
// Import individual browser (and isomorphic) functions, types, classes, etc.
import {
browserVersion,
browserEngineVersion,
getUserAgentString,
assignFrozenClone
} from 'mad-utils/lib/node';
If using a high-level import (mUtils, m_, __), you can access functions either via their namespaces or directory. E.g.
mUtils.search.replaceAll
mUtils.replaceAll
__.number.isInt
__.isInt
m_.date.isLeapYear
m_.isLeapYear
m_.array.secondLast
m_.secondLast
...etc...
mUtils
, __
, and m_
are 'full collection' exports
You can also get them like this if you hate named imports:
import madUtils from 'mad-utils';
const h = madUtils.m_;
Inclusive, overlapping namespace strategy used.
Namespaces treated more like keywords than parent types.
The main philosophy behind this API design is to make common functions maximally available.
Either a number, or a string that can be parsed to a number
Either a string, or 'Never' (indicating an error threw in the function)
Return first item in given array
first(['a', 'b', 'c', 'd']); // => 'a'
Return second item in given array
second(['a', 'b', 'c', 'd']); // => 'b'
Return third item in given array
third(['a', 'b', 'c', 'd']); // => 'c'
Return last item in given array
last(['a', 'b', 'c', 'd']); // => 'd'
Return secondLast item in given array
secondLast(['a', 'b', 'c', 'd']); // => 'c'
Return thirdLast item in given array
thirdLast(['a', 'b', 'c', 'd']); // => 'b'
Return first 2 items in given array
first2(['a', 'b', 'c', 'd']); // => ['a', 'b']
Return first 3 items in given array
first3(['a', 'b', 'c', 'd']); // => ['a', 'b', 'c']
Return last 2 items in given array
last2(['a', 'b', 'c', 'd']); // => ['c', 'd']
Return last 3 items in given array
last3(['a', 'b', 'c', 'd']); // => ['b', 'c', 'd']
Return first 'n' number of items from given array
firstN(['a', 'b', 'c', 'd'], 2); // => ['a', 'b']
Return last 'n' items from given array. Return full array if too many items requested.
lastN(['a', 'b', 'c', 'd'], 2); // => ['c', 'd']
Create empty array of given length (integer).
arrayN(3); // => [undefined, undefined, undefined]
Split large multiline string into array where each line is an item. Removes blank lines by default, unless preserveEmptyLines option is set to true.
splitLines(
'first line' +
'\n ' +
'third line' +
'\n',
'fourth line'
);
// => ['first line', ' ', 'third line', 'fourth line']
splitLines(`
first line
second line`,
{preserveEmptyLines: true}
);
// => ['', 'first line', '', 'second line']
Remove first character or array item.
withoutFirst([1, 2, 3, 4, 5]) // => [2, 3, 4, 5]
withoutFirst('hello'); // => 'ello'
Remove first 2 characters or array items.
withoutFirst2([1, 2, 3, 4, 5]); // => [3, 4, 5]
withoutFirst2('abcdef'); // => 'cdef'
Remove first 3 characters or array items.
withoutFirst3([1, 2, 3, 4, 5]); // => [4, 5]
Remove last character or array item.
withoutLast([1, 2, 3, 4, 5]); // => [1, 2, 3, 4]
Remove last 2 characters or array items.
withoutLast2([1, 2, 3, 4, 5]); // => [1, 2, 3]
Remove last 3 characters or array items.
withoutLast3([1, 2, 3, 4, 5]); // => [1, 2]
Remove first N characters or array items.
withoutFirstN([1, 2, 3, 4, 5], 3); // => [4, 5]
Remove last N characters or array items.
withoutLastN([1, 2, 3, 4, 5], 3); // => [1, 2]
True if item is an array
isArray([]); // => true
class CustomArray extends Array { }
isArray(new CustomArray()); // => true
NON-MUTATIVE. PERFORMANCE-INTENSIVE.
Return new array with all items in arr2OrItem removed from array1. If array2 is not an array, remove matching item from array1.
removeMatches([1, 2, 3], 2); // => [1, 3]
removeMatches([1, 2, 3, 4, 5], [1, 4]); // => [2, 3, 5]
(arr: any[]) => arr[]
Examples:
rmAllFalsy([1, 2, 3, false, null, 4, 0, 'asdf', '', 'ok', undefined, 'fine']);
// => [1, 2, 3, 4, 'asdf', 'ok']
Search an array for a value.
Note that it uses simple JSON.stringify for array and object comparison
Sane behaviour for matching against null, undefined, NaN, etc.
Curried.
Examples:
matchAny([1, 2, 3])(2);
// => true
matchAny(['a', 6, [1, 2, 3], 'gr'])([1, 2, 3]);
// => true
matchAny(['a', 6, null, 'last'])(null);
// => true
Shorthand for any number between 0 and 6
String that creates a timestamp in a nice, human-readable format when passed to MomentJS.
YYYY/MM/DD : hh:mm:ss
Examples:
console.log(defaultTimestampFormat);
// => `YYYY/MM/DD : HH:mm:ss`;
Returns true if given year is a leap year. Accepts integers, strings that can be converted to integers, and arrays with a single item, where said item is an integer or string convertable to an integer. Any other input will throw.
Examples:
isLeapYear(2004); // => true
isLeapYear(2003); // => false
Converts numeric day of the week to string day of the week. e.g. 0 -> 'Sunday', 6 -> 'Saturday' Args:
Examples:
convertDayOfWeekNumToString(5); // => 'Friday'
convertDayOfWeekNumToString(2, true); // => 'Tues'
(timeFormat?: string) => string
MM/DD::hh:mm:ss
Examples:
now(); // => 2017/05/28 : 02:51:39
now(`YYYY/MM hh:mm`); // => 2017/02 02:51
Return raw and unparsed browser user agent string (convenience function)
Example:
getUserAgentString();
// => "Mozilla/4.0 (Macintosh; Intel Mac OS X 7_12_6) AppleWebKit/501.16 (KHTML, like Gecko) Chrome/50.0.1010.99 Safari/210.22"
Extract name of current user's OS (operating system) from browser user agent string. (Note: Memoizes result - i.e. 1st call to function stores result; all future calls reference stored result).
Example:
osName(); // => "Mac OS"
Extract name of OS from browser user agent string, & convert it to snake_case. (Note: memoizes result)
Example:
osNameSnakeCase(); // => "mac_os"
Extract name of current browser from browser user agent string. (Note: memoizes result)
Example:
browserName(); // => "Firefox"
Extract name of current browser's rendering engine from browser user agent string. (Note: memoizes result)
Example:
browserEngineName(); // => "Webkit"
Extract version of current OS from browser user agent string. (Note: memoizes result)
Example:
osVersion(); // => "15.9.1"
Extract version of current browser from browser user agent string. (Note: memoizes result)
Example:
browserVersion(); // => "64.1.5284.259"
Extract version of current browser's rendering engine from browser's user agent string. (Note: memoizes result)
Example:
browserEngineVersion(); // => "530.12"
Remove pointless stacktrace items (node core). Modify the stacktrace length to be unlimited. Effects get applied globally immediately on running the function.
Examples:
globalActivateCleanStack();
// /\-- This is literally the only way to use it.
Returns true if inode (aka file, directory, socket, etc.) at absolute path is a directory.
isDir(path.join(rootPath, 'node_modules')); // => isTrue
Must always be called like this: wasRunAsScript(path.basename(__filename))
.
WARNING: has some edge cases (Fixing them is a WIP TODO):
Example (in some-file.js, with process launched via node some-file.js
):
wasRunAsScript(path.basename(__filename)); // => true
WIP documentation
WIP documentation
WIP documentation
WIP documentation
WIP documentation
True if the given string (generally a path) ends in .js
.
Example:
endsInDotJs(`asdf.js`); // => true
WIP documentation
Function-based switch statement.
For each pair of args:
If no conditions pass, and there was:
Examples:
switchExpr(true, 'val1'); // => 'val1'
switchExpr(true, 'val1', 'defaultVal'); // => 'val1'
switchExpr(false, 'val1', 'defaultVal'); // => 'defaultVal'
switchExpr(false, 'v1', 'condition1', 'v2'); // => 'v2'
switchExpr(false, 'v1', null, 'v2', 'defaultReturnVal'); // => 'v2'
switchExpr(false, 'v1', null, 'v2'); // => [throws error]
switchExpr(false, 'v1'); // => [throws error]
let size = 'large';
switchExpr(
size === 'tiny', 8,
size === 'small', 10,
size === 'medium', 12,
size === 'large', 16,
size === 'huge', 20,
12
);
// => 16
General syntax:
switchExpr(
COND1, val_returned_if_COND1_truthy,
COND2, val_returned_if_COND2_truthy,
...,
defaultReturnVal
)
Run given function the given number of times.
Return results of all runs of the function as an array containing all N return vals.
Examples:
loopN(2, () => 'return_value'); // => ['return_value', 'return_value']
let i = 0;
loopN(10, () => i++); // => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
console.log(i) // => 10
Run given function twice, and return results of both runs of the function as an array.
Example:
loop2(() => 'return_value'); // => ['return_value', 'return_value']
See loop2 above, but run the associated number of times
Examples:
loop3(() => 'ret_val'); // => ['ret_val', 'ret_val', 'ret_val']
loop4(() => 'ret_val'); // => ['ret_val', 'ret_val', 'ret_val', 'ret_val']
loop5(() => 'ret_val'); // => ['ret_val', 'ret_val', 'ret_val', 'ret_val', 'ret_val']
let i = 0;
loop5(() => i++); // => [0, 1, 2, 3, 4]
console.log(i) // => 5
Return a function's source code in nicely spaced array format.
Examples:
getFnAsArr(() => 'ok')
// => [ 'function () { return \'ok\'; }' ]
function testFn() {
console.log('log 1');
return 'output';
}
getFnAsArr(testFn);
// => [ 'function testFn() {',
// ' console.log(\'log 1\');',
// ' return \'output\';',
// '}']
Stringify, while keeping the functions in position by pre-converting them to strings.
Example:
jsonStringifyWFuncs({a: 123, b: 'asdf', c: () => 'asdf'})
// =>
'{"a":123,"b":"asdf","c":"function () { return \'asdf\'; }"}'
WIP documentation
{af: 'Afrikaans', en: 'English', ...}
['af', 'en', ...]
['Afrikaans', 'English', ...]
{en:
English, fr:
French}
['en', 'fr']
['English', 'French']
['english', 'en', 'en_ca', 'en_us', ...]
['french', 'fr', 'fr_fr', 'fr_ca', ...]
WIP documentation
WIP documentation
Returns true if given value is an integer.
Examples:
isInteger(1); // => true
isInteger(232); // => true
isInteger(82.12); // => false
isInteger('232'); // => false
isInteger('asdf'); // => false
(Alias: isInt)
Returns true if given value is an integer-like string or integer.
Examples:
isIntegerLike(232); // => true
isIntegerLike('232'); // => true
isIntegerLike('asdf'); // => false
isInteger(82.12); // => false
Returns true if given value is a number-like string or number.
Examples:
isNumberLike(1); // => true
isNumberLike(9267.84); // => true
isNumberLike('1'); // => true
isNumberLike('9267.84'); // => true
isNumberLike('1.2'); // => true
isNumberLike('.2'); // => true
isNumberLike('1.2.2'); // => false
isNumberLike('asdf'); // => false
isNumberLike(true); // => false
(Alias: isNumLike)
Generate a UUID, in format e.g. 3A0BF2C7-3077-45A0-97ED-EC5F13F127F1
.
Examples:
uuid(); // => 'F6779B17-8CD1-409B-A2AA-1FE80CB86654'
uuid(); // => 'B574571F-097A-4ADB-837C-DCE8472C3314'
Safely get the item at the given object path.
Arguments:
Examples:
const obj = {a: {b: {c: 'value'}}};
get(obj, 'a.b.c'); // => 'value'
get(obj, 'a.b.zzz', 'default value'); // => 'default value'
Non-mutatively merge all given objects together (like Object.assign) & deep-freeze the result.
Examples:
const obj = assignFrozenClone({a: 1, b: 2}, {c: 3, d: 4});
// => {a: 1, b: 2, c: 3, d: 4}
obj.a = 6;
obj.a // => 1
^--- note that it didn't change
Deep freeze given object MUTATIVE! (But still returns original)
Examples:
const obj = deepFreeze({a: 1, b: 2, c: 3, d: 4});
// obj = {a: 1, b: 2, c: 3, d: 4}
obj.a = 6;
console.log(obj.a); // => 1
// ^--- note that it didn't change
// Note that it also mutates the object:
const obj = {a: 1, b: 2, c: 3, d: 4};
deepFreeze(obj);
obj.a = 6;
console.log(obj.a); // => 1
Run given function on each pair in given object. CURRIED, NON-MUTATIVE.
Examples:
const arr = [];
const putKeyValPairInArr = eachPair((v, k) => arr.push(k + v));
putKeyValPairInArr({a: 1, b: 2});
console.log(arr); // => ['a1', 'b2']
Return number of keys in given object.
Examples:
numKeys({a: 1, b: 2}); // => 2
Return true if given object has given key.
Examples:
hasKey({a: 1, b: 2}, 'a'); // => true
hasKey({a: 1, b: 2}, 'c'); // => false
Add {key} with value {val} to {obj}. If {mutable} true, make new prop mutable.
Generics:
Arguments:
Return value: (InputObject & NewKVPair)
Examples:
const obj = {a: 'eh', b: 'bee'}
defineProps(obj, 'c', 'sea');
// returns (and new value of obj) :: {a: 'eh', b: 'bee', c: 'sea'}
const obj = {a: 'eh', b: 'bee'}
defineProps(obj, 'c', 'sea');
defineProps(obj, 'c', 'seeeee');
// returns (and new value of obj) :: {a: 'eh', b: 'bee', c: 'sea'}
const obj = {a: 'eh', b: 'bee'}
defineProps(obj, 'c', 'sea', true);
defineProps(obj, 'c', 'seeeee', true);
// returns (and new value of obj) :: {a: 'eh', b: 'bee', c: 'seeeee'}
Signature:
(
string? = window.location.pathname,
string[]? = ['en','fr'],
string? = 'en'
) => string
Get the currently selected language out of the current URL.
Note: this is a 'rough' method not intended to work in all circumstances.
In Node, default value window.location.pathname gets set to '' if it doesn't exist.
Examples:
// Assuming we're at URL 'http://example.com/auth/fr/ok':
getLangFromURLPathname();
// => 'fr'
// Assuming we're at URL 'http://example.com/auth/fr/ok':
getLangFromURLPathname(window.location.pathname);
// => 'fr'
getLangFromURLPathname('/asdf/123asdfawzu/en/eiuherg/awzp1');
// => 'en'
getLangFromURLPathname('/asdf/123asdfawzu/sp/eiuherg/awzp1', ['en', 'sp']);
// => 'sp'
getLangFromURLPathname('/asdf/123asdfawzu/au/eiuherg/awzp1', ['en', 'fr', 'sp']);
// => 'en'
getLangFromURLPathname('/asdf/123asdfawzu/au/eiuherg/awzp1', ['en', 'fr', 'sp'], 'fr');
// => 'fr'
Convert the current query params into an object.
Note that running it without explicitly passing the queryParamsString works, but can give stale results.
Examples (at URL 'http://example.com/home?hello=everyone&gr=argh'
):
parseQueryParams(window.location.search);
// => {hello: 'everyone', gr: 'argh'}
parseQueryParams();
// => {hello: 'everyone', gr: 'argh'}
Get the last path in the given URL, with no / prepended, & query params excluded.
Returns '' if no paths in url.
Sets 'strict mode' to true by default, meaning trailing slashes aren't ignored.
If first param is null or undefined, uses the current page's URL as the url value.
Examples:
// Assuming we're at URL 'http://example.com/home?hello=everyone&gr=argh'
lastUrlPath(); // => 'home'
// Assuming we're at URL 'http://example.com/asdf/?hello=everyone&gr=argh'
lastUrlPath(); // => ''
lastUrlPath(null, false); // => 'asdf'
lastUrlPath('http://example.com'); // => ''
lastUrlPath('http://example.com/'); // => ''
lastUrlPath('http://example.com/', false); // => ''
lastUrlPath('http://example.com/asdf'); // => 'asdf'
lastUrlPath('http://example.com/asdf/'); // => ''
lastUrlPath('http://example.com/asdf/', false); // => 'asdf'
Normalize given [url] {string}, converting to this format:
/main/en/home
/main/en/home?key=value
Does the following actions:
/
/
//
-> /
; ///
-> /
)/?
with ?
Examples:
normalizeURLPathname(``); // Output: ``
normalizeURLPathname(`/asdf/123`); // Output: `/asdf/123`
normalizeURLPathname(` / `); // Output: `/`
normalizeURLPathname(`/////`); // Output: `/`
normalizeURLPathname(`/asdf//123`); // Output: `/asdf/123`
normalizeURLPathname(`asdf`); // Output: `/asdf`
normalizeURLPathname(`/asdf/?key=val`); // Output: `/asdf?key=val`
normalizeURLPathname(` ab//cd/ef///?key=val/ `); // Output: `/ab/cd/ef?key=val`
Make the first letter uppercase and the rest lowercase.
Examples:
cap1LowerRest('asdf'); // => 'Asdf'
cap1LowerRest('aSdF'); // => 'Asdf'
cap1LowerRest('This was already cap.'); // => 'This was already cap.'
cap1LowerRest('This Was Already Cap.'); // => 'This was already cap.'
cap1LowerRest('not Already Cap.'); // => 'Not already cap.'
Make the first letter uppercase, and leave the rest as-is.
Examples:
capitalize('asdf'); // => 'Asdf'
capitalize('aSdF'); // => 'ASdF'
capitalize('This was already cap.'); // => 'This was already cap.'
capitalize('not Already Cap.'); // => 'Not Already Cap.'
Return copy of string with all instances of substring or regexp (matcherToRm) removed.
Examples:
removeMatchingText('HeRMlloRM woRMrldRM', 'RM'); // => 'Hello world'
removeMatchingText('RMqwertyRM uioprm', /rm ?/ig); // => 'qwertyuiop'
removeMatchingText('Hello world', 'ASafer'); // => 'Hello world'
Replace all matching strings or regexes in a text segment with given replacement string. All matching strings get replaced.
Args:
Examples:
replaceAll('The duck here is the best Jerry! The best!', 'best', 'bees-knees');
// => 'The duck here is the bees-knees Jerry! The bees-knees!'
replaceAll('The duck here is the best Jerry! The best!', /[tT]he best/g, 'OK');
// => 'The duck here is OK Jerry! OK!'
Remove all chars in charsToChomp string from end of given string (1st arg).
Defaults to eliminating carriage return and newline (\n\r).
Examples:
chomp('asdf\n\r\n\r'); // => 'asdf'
chomp('asdf\n \r \n\r', '\n\r '); // => 'asdf'
chomp('\n \ras\ndf\n \r \n\r ', '\n\r '); // => '\n \ras\ndf'
chomp('asdf\r \n', ' \n'); // => 'asdf\r'
Create Mocha test that passes if given object exists and is not empty
Examples:
expectEmptyObject({}); // << will not pass
expectEmptyObject({ a: 1 }); // << will pass
Create Mocha test that passes if given object is empty
Examples:
expectEmptyObject({}); // << will pass
expectEmptyObject({ a: 1 }); // << will not pass
Create Mocha test that passes if given function exists
Examples:
const inc = (a: number) => a + 1;
expectFunctionExists({}); // << will not pass
expectFunctionExists(() => null); // << will pass
expectFunctionExists(inc); // << will pass
Return true if arg is a moment or Date instance; or a string, object, or number that moment can parse.
Excludes:
Examples:
isDateLike('1990-12-10'); // => true
isDateLike(moment()); // => true
isDateLike(new Date()); // => true
isDateLike('asdf'); // => false
isDateLike(false); // => false
Return true if arg is a boolean value (either true or false)
Examples:
isBoolean(false); // => true
isBoolean(true); // => true
isBoolean(Boolean(true)); // => true
isBoolean(''); // => false
isBoolean(0); // => false
isBoolean('true'); // => false
isBoolean(() => true); // => false
WIP documentation
WIP documentation
WIP documentation
WIP documentation
WIP documentation
WIP documentation
WIP documentation
WIP documentation
WIP documentation
WIP documentation
WIP documentation
WIP documentation
WIP documentation
WIP documentation
Documentation is a major WIP. TODO More documentation in README. TODO Document special React module.
FAQs
A set of misc utilties I find myself repeatedly re-writing between projects.
The npm package mad-utils receives a total of 240 weekly downloads. As such, mad-utils popularity was classified as not popular.
We found that mad-utils demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Socket uncovers malicious Rust crates impersonating fast_log to steal Solana and Ethereum wallet keys from source code.
Research
A malicious package uses a QR code as steganography in an innovative technique.
Research
/Security News
Socket identified 80 fake candidates targeting engineering roles, including suspected North Korean operators, exposing the new reality of hiring as a security function.