- Installation
- Usage
- Credits
$ npm add --save-dev @fullstacksjs/toolbox
or using yarn
$ yarn add --dev @fullstacksjs/toolbox
force a value to an array
ensureArray(value)
ensureArray(null); // [null]
ensureArray(undefined); // [undefined]
ensureArray('string'); // ['string']
ensureArray(['array']); // ['array']
ensureArray([1, 2, 3]); // [1, 2, 3]
ensureArray({ foo: 'bar' }); // [{ foo: 'bar' }]
get a random element from an array
getRandom([1, 2, 3]); // 1 or 2 or 3
getRandom([]); // undefined
getRandom('list'); // Error: not an array
create array of length n with from offset with an step
range(length, { offset, step })
range(0); // []
range(10); // [0,1,2,3,4,5,6,7,8,9]
range(3, { offset: 5 }); // [5,6,7]
range(3, { offset: -2, step: 10}); // [-2, 8, 18]
Convert a value to an array
toArray(value)
toArray(null); // []
toArray(undefined); // []
toArray('string'); // ['string']
toArray(['array']); // ['array']
toArray(iteratable); // [...iteratable]
toArray(others); // [others]
Gets an array and return shallow copy version of it
copyArray([]); // []
copyArray([1]); // []
Gets an array and return a shuffled version of it
copyArray([]); // []
copyArray([1]); // [1]
copyArray([1, 2, 3 ,4 , 5]); // [2, 1, 3, 4, 5]
filters nulls from array
compact([1, false, null, 2, undefined]); // [1, false, 2]
compact([NaN, false, null, 0, undefined]); // [NaN, false, 0]
concatNullableArrays(...maybeArrays)
concatNullableArrays(null); // []
concatNullableArrays(undefined); // []
concatNullableArrays([]); // []
concatNullableArrays([1]); // [1]
concatNullableArrays(undefined, [1, 2], null); // [1,2]
concatNullableArrays(undefined, [1, 2], null, [2, 3]); // [1, 2, 2, 3]
return whether an array is empty or not
isEmpty([]) // true
isEmpty([1]) // false
isEmpty([[], [], []]) // false
isEmpty([undefined]) // false
isEmpty([null]) // false
isEmpty([,]) // false
isEmpty([, null]) // false
isEmpty([, undefined]) // false
is an index is the last index in an array
isLastIndex([], 0) // false
isLastIndex([1], 0) // true
isLastIndex([1, 2], 1) // true
isLastIndex([], -1) // false
isLastIndex([[], [], []], 0) // false
isLastIndex([[], [], []], 2) // true
isLastIndex([undefined], 0) // true
isLastIndex([null], 0) // true
isLastIndex([,], 0) // true
isLastIndex([, null], 1) // true
isLastIndex([, undefined], 1) // true
join path parts with "/" and without trailing and leading slashes
joinPath(['a', 'b']) // 'a/b'
joinPath(['a', '/b']) // 'a/b'
joinPath(['a', 'b/']) // 'a/b'
joinPath(['a', '/b/']) // 'a/b'
joinPath(['a/', 'b']) // 'a/b'
joinPath(['a/', '/b']) // 'a/b'
joinPath(['a/', 'b/']) // 'a/b'
joinPath(['a/', '/b/']) // 'a/b'
joinPath(['/a', 'b']) // 'a/b'
joinPath(['/a', '/b']) // 'a/b'
joinPath(['/a', 'b/']) // 'a/b'
joinPath(['/a', '/b/']) // 'a/b'
joinPath(['https://a.com', 'b']) // 'https://a.com/b'
joinPath(['https://a.com', '/b']) // 'https://a.com/b'
joinPath(['https://a.com', 'b/']) // 'https://a.com/b'
joinPath(['https://a.com/', '/b/']) // 'https://a.com/b'
joinPath(['https://a.com/', '?b=a']) // 'https://a.com/?b=a'
joinPath(['https://a.com/', '/b/', '?query']) // 'https://a.com/b/?query',
joinPath(['https://a.com/', '?query', '&a=query']) // 'https://a.com/?query/&a=query',
get environment variable or given fallback
getEnv<TEnvKey, TValue>(name, fallback)
// FOO=foo BAR=bar node
Env.getEnv<TEnvKey>('FOO'); // foo
Env.getEnv<TEnvKey>('BAR'); // undefined
Env.getEnv<TEnvKey>('BAR', 'bar'); // bar
Parse an environment to a boolean or throw error. If env does not exist, it returns the fallback value.
getBooleanEnv(name, fallback): boolean | undefined
// j={} f=foo t=true f=false node
Env.getBooleanEnv<TEnvKey>('j'); // <Error>
Env.getBooleanEnv<TEnvKey>('f'); // <Error>
Env.getBooleanEnv<TEnvKey>('t'); // true
Env.getBooleanEnv<TEnvKey>('f'); // false
Env.getBooleanEnv<TEnvKey>('n'); // undefined
Env.getBooleanEnv<TEnvKey>('n', false); // false
Env.getBooleanEnv<TEnvKey>('n', true); // true
get environment variable or throw
getRequiredEnv<TEnvKey, TValue>(name)
// FOO=foo BAR=bar node
Env.getRequiredEnv<TEnvKey>('FOO'); // foo
Env.getRequiredEnv<TENvKey>('BAR'); // Error: BAR is required
give NODE_ENV value or given fallback value
getNodeEnv(fallback)
// NODE_ENV=anything node
Env.getNodeEnv(); // undefined
Env.getNodeEnv<'anything'>('anything'); // 'anything'
Env.getNodeEnv<'not'>('not'); // undefined
strict check NODE_ENV with given value
// NODE_ENV=production node
Env.is('development'); // false
Env.is('production'); // true
check env is 'development'
// NODE_ENV=development node
Env.isDev; // true
check env is 'production'
// NODE_ENV=production node
Env.isProd; // true
check env is 'test'
// NODE_ENV=test node
Env.isTest; // true
No operation ¯\_(ツ)_/¯
noop() // undefined
HOC that call all given functions
callAll(foo, bar, baz)(...args) // void (foo(...args), bar(...args), baz(...args));
callAll(bar,'string', 5, null, undefined, baz)(...args) // void (bar(...args), baz(...args));
returns the "NOT" of its argument
not(true) // false
not(false) // true
not(0) // true
returns true if specified minimum predicates pass the given value otherwise false
const isDivisibleBy3 = x => x % 3 === 0
const isDivisibleBy5 = x => x % 5 === 0
const isLargerThan25 = x => x > 25
const isValidNumber = x => passesMin(2, [isDivisibleBy3, isDivisibleBy5, isSmallerThan25], x);
isValidNumber(15) //returns true because its divisible by 5 and 3
isValidNumber(3) //returns false because its only divisible by 3
isValidNumber(26) //returns false because its only larger than 25
isValidNumber(30) //returns true because its passes minimum 2 cases (being divisible by 5 and 3 and larger than 25)
check given value is boolean or not
isBoolean(true); // true
isBoolean(false); // true
isBoolean(); // false
isBoolean(1); // false
isBoolean(['1']); // false
isBoolean('1'); // false
check given value is string or not
isString(); // false
isString(1); // false
isString(['1']); // false
isString('1'); // true
check given value is iterable or not
isIterable([]); // true
isIterable(new Map()); // true
isIterable({ [Symbol.iterator]() { } }); // true
isIterable('some'); // true
isIterable({}); // false
isIterable(); // false
check given value is function or not
isFunction(() => {}); // true
isFunction(); // false
isFunction(true); // false
check given value is either null or undefined
isNull(undefined) // true
isNull(null) // true
isNull(0) // false
isNull(false); // false
isNull({}); // false
isNotNull([]); // false
check given value is neither null nor undefined
isNotNull(undefined) // false
isNotNull(null) // false
isNotNull(0) // true
isNotNull(false); // true
isNotNull({}); // true
isNotNull([]); // true
check given value is truthy
isNotNull(undefined) // false
isNotNull(null) // false
isNotNull(0) // false
isNotNull(false); // false
isNotNull({}); // true
isNotNull([]); // true
isNotNull(NaN); // false
check given value is an object
isObject('hello world'); // false
isObject(null); // false
isObject(true); // false
isObject([]); // false
isObject({ x: 'word'}); // true
isObject({ 2: 'numeric index'}); // true
divide two numbers returns fallback if result is not a finite number
safeDivide(4, 2); // 2
safeDivide(4, 0); // 0
safeDivide(null, NaN); // 0
safeDivide(null, NaN, 10); // 10
safeDivide(4, 0, 'Oops'); // 'Oops'
clamp a number between two values
clamp(-10); // 0
clamp(10); // 1
clamp(-10, { min: -5 }); // -5
clamp(30 , { max: 20 }); // 20
clamp(5 , { min: -20, max: 20 }); // 5
generate random integer number between range.
randomRange(); // <random> 0 -> Number.MAX_SAFE_INTEGER
randomRange({ min: -10, max: 50 }); // <random> -10 -> 50
randomRange({ max: 50 }); // <random> 0 -> 50
randomRange({ min: 50 }); // <random> 50 -> Number.MAX_SAFE_INTEGER
parse string to integer (radix 10), returns fallback if result is NaN.
toInteger('100'); // 100
toInteger('1.42'); // 1
toInteger('?'); // NaN
toInteger('?', 1); // 1
toInteger('?', 1.5); // 1.5
toInteger('?', NaN); // NaN
toInteger('?', undefined); // NaN
Checks if num is between min and max (and including borders).
isInRange(100, { min: 0 , max: 50 }); // false
isInRange(100, { min: 0 , max: 100 }); // true
isInRange(100, { min: 50 , max: 150 }); // true
isInRange(100, { min: 100, max: 150 }); // true
remove null and empty property from an object
pruneNullOrEmpty({ name: 'John', age: null, status: '', nickname: undefined }) // { name: 'John' }
pruneNullOrEmpty({ foo: { bar: null } }) // { foo: { bar: null } }
pruneNullOrEmpty({ foo: {} }) // { foo: {} }
pruneNullOrEmpty({ foo: { length: 0 } }) // { foo: { length: 0 } }
pruneNullOrEmpty({ foo: [] }) // { foo: [] }
remove null and empty property from an object
pruneUndefinedOrEmpty({ name: 'John', age: null, status: '', nickname: undefined }) // { name: 'John', nickname: null }
pruneUndefinedOrEmpty({ foo: { bar: null } }) // { foo: { bar: null } }
pruneUndefinedOrEmpty({ foo: {} }) // { foo: {} }
pruneUndefinedOrEmpty({ foo: { length: 0 } }) // { foo: { length: 0 } }
pruneUndefinedOrEmpty({ foo: [] }) // { foo: [] }
convert any casing to space separated lowercase
toSpaceCase(''); // ''
toSpaceCase('foo bar'); // 'foo bar'
toSpaceCase('foo-bar'); // 'foo bar'
toSpaceCase('fooBar'); // 'foo bar'
toSpaceCase('foo_bar'); // 'foo bar'
toSpaceCase('FOO-barCode'); // 'foo bar code'
toSpaceCase('foo -bar _BAZ'); // 'foo -bar _baz'
transforms a valid casing to camelCase if the given value is invalid it just returns the input
toCamelCase(''); // ''
toCamelCase('foo bar'); // 'fooBar'
toCamelCase('foo-bar'); // 'fooBar'
toCamelCase('fooBar'); // 'fooBar'
toCamelCase('foo_bar'); // 'fooBar'
toCamelCase('FOO-barCode'); // 'FOO-barCode'
transforms a valid casing to snake_case if the given value is invalid it just returns the input
toCamelCase(''); // ''
toCamelCase('foo bar'); // 'foo_bar'
toCamelCase('foo-bar'); // 'foo_bar'
toCamelCase('fooBar'); // 'foo_bar'
toCamelCase('foo_bar'); // 'foo_bar'
toCamelCase('FOO-barCode'); // 'FOO-barCode'
transforms a valid casing to kebab-case if the given value is invalid it just returns the input
toCamelCase(''); // ''
toCamelCase('foo bar'); // 'foo-bar'
toCamelCase('foo-bar'); // 'foo-bar'
toCamelCase('fooBar'); // 'foo-bar'
toCamelCase('foo_bar'); // 'foo-bar'
toCamelCase('FOO-barCode'); // 'FOO-barCode'
transforms a valid casing to PascalCase if the given value is invalid it just returns the input
toCamelCase(''); // ''
toCamelCase('foo bar'); // 'FooBar'
toCamelCase('foo-bar'); // 'FooBar'
toCamelCase('fooBar'); // 'FooBar'
toCamelCase('foo_bar'); // 'FooBar'
toCamelCase('FOO-barCode'); // 'FOO-barCode'
check given value is null/undefined/empty string/array or not
isNullOrEmpty(); // true
isNullOrEmpty(null); // true
isNullOrEmpty(undefined); // true
isNullOrEmpty(''); // true
isNullOrEmpty('f'); // false
isNullOrEmpty(1); // false
isNullOrEmpty([]); // true
isNullOrEmpty([1,2,3]); // false
Removing trailing slashes from a string
removeTrailingSlashes(''); // ''
removeTrailingSlashes('/'); // ''
removeTrailingSlashes('string'); // string
removeTrailingSlashes('string/'); // string
removeTrailingSlashes('string//'); // string
removeTrailingSlashes('/string//'); // /string
removeTrailingSlashes('https://domain.com/path/'); // https://domain.com/path
removeTrailingSlashes('https://domain.com/path//'); // https://domain.com/path
Removing leading slashes from a string
removeLeadingSlashes(''); // ''
removeLeadingSlashes('/'); // ''
removeLeadingSlashes('string'); // 'string'
removeLeadingSlashes('/string'); // 'string'
removeLeadingSlashes('//string'); // 'string'
removeLeadingSlashes('//string/'); // 'string/'
removeLeadingSlashes('//string/a'); // 'string/a'
Check if a string passes a specific regex
testRegex(/[A-Z]/, "Abc") // true
testRegex(/^\d+$/, "2021") // true
testRegex(/[a-z]/, "( ͡° ͜ʖ ͡°)") // false
const r = /abc/g
r.test('abc') // true
r.test('abc') // false
testRegex(r, 'abc') // true
testRegex(r, 'abc') // true
throws the given value
throwError(new Error('msg')) // Uncaught Error: msg
throwErr('error') // Uncaught 'error'
throwErr(404) // Uncaught 404
throwError({}) // Uncaught {}
throws an error when the condition is false.
assert(false) // throw new Error('Assertion failed')
assert(false, 'Error') // throw new Error('Error')
assert(true, 'Error') // undefined
throwError(new Error('msg')) // Uncaught Error: msg
throwErr('error') // Uncaught 'error'
throwErr(404) // Uncaught 404
throwError({}) // Uncaught {}
bind nullable function together
const f = (x: string): string[] => x.split('');
const g = (x: string[]): number => Number.parseInt(x[0]!, 10);
const h = (x: number): Nullable<number> => (Number.isNaN(x) ? null : x);
const k = (x: number): string => (x === 2 ? 'yes' : 'no');
bind('2', f, g, h, k); // 'yes'
bind('3', f, g, h, k); // 'no'
bind('n', f, g, h, k); // null
bind(null, f, g, h, k); // null
type name = Nullable<string> // null | string
Type guard for truthy values
type X = 1 | 0 | '' | boolean | null | 'String';
type TX = Truthy<X> // 1 | true | 'String'
Converts snake_case values in a type to camelCase
type X = 'literal_item_0' | 'LITERAL_ITEM_1' | 'LiTeraL_ItEm_2' | 'it_a_recursive_types';
type TX = CamelCase<X> // 'literalItem0' | 'literalItem1' | 'literalItem2' | 'itsARecursiveTypes';
Predicate function type
type Predicate<T> // (a: T) => boolean;
type MaybePromise<T> // T | Promise<T>;
type VoidFn = (...args: any) => void | Promise<void>;
type VoidFn<T> = ( ...args: T) => void | Promise<void>;
type EnvironmentVariable = string | undefined;
type EnvironmentVariable<T> = T | undefined;
type NodeEnv = 'production' | 'development | undefined;
type NodeEnv<T> = 'production' | 'development | undefined | T;
const foo = {
bar: {
baz: {
qux: 'qux',
},
},
};
type FooObjectPath = ObjectPath<typeof foo>; // "bar" | "bar.baz" | "bar.baz.qux"
Create type from type T
with K
keys are required.
interface Foo {
x? : string;
y?: string;
}
type Bar = RequiredBy<T, 'x'> // { x: string, y?: string }
Create type from type T
with K
keys are optional.
interface Foo {
x : string;
y: string;
}
type Bar = PartialBy<T, 'x'> // { x?: string, y: string }
type Arr = FilterNullish<(number | undefined | string | null)[]> // (number | string)[]
type Tuple = FilterNullish<[number, null, string, undefined]> // [number, string]
type RArr = FilterNullish<readonly (number | undefined | string | null)[]> // readonly (number | string)[]
type RTuple = FilterNullish<readonly [number, null, string, undefined]> // readonly [number, string]
type T = Tuple<string, 3> // [string, string, string]
type T = Tuple<undefined, 2> // [undefined, undefined]