A collection of useful little things that I like to reuse across projects


License
MIT
Install
npm install swiss-ak@3.4.2

Documentation

swiss-ak (Swiss Army Knife)

A collection of useful little things that I like to reuse across projects

times

A collection of Tools for calculating simple times. Each unit (e.g. second) has: a type (second), a constant (SECOND) and a function for getting multiples (seconds(x: second) => ms)

unit type constant function
millisecond ms MILLISECOND milliseconds(x: ms) => ms
second second SECOND seconds(x: second) => ms
minute minute MINUTE minutes(x: minute) => ms
hour hour HOUR hours(x: hour) => ms
day day DAY days(x: day) => ms
week week WEEK weeks(x: week) => ms
month month MONTH months(x: month) => ms
year year YEAR years(x: year) => ms
decade decade DECADE decades(x: decade) => ms
century century CENTURY centuries(x: century) => ms
millennium millennium MILLENNIUM millenniums(x: millennium) => ms

[↑ Back to top ↑]

waiters

Async functions that return promises at or after a given time.

'Accurate/pinged' waiters ping at intermediary points to resolve at a more accurate time.

Name Description Example
wait Standard wait promise (using setTimeout) minutes(2) = in 2 minutes
waitFor Accurate (pinged) wait the given ms minutes(2) = in 2 minutes
waitUntil Accurate (pinged) wait until given time Date.now() + minutes(2) = in 2 minutes
waitEvery Accurate (pinged) wait for next 'every X' event hours(1) = next full hour (e.g. 17:00, 22:00)
interval Accurate (pinged) interval for every 'every X' event hours(1) = every hour, on the hour

[↑ Back to top ↑]

wait

wait(time: ms): Promise<unknown>
waiters.wait(time: ms): Promise<unknown>

Standard wait promise (using setTimeout)

import { wait } from 'swiss-ak';

console.log(new Date().toTimeString()); // 12:30:10
await wait(minutes(2));
console.log(new Date().toTimeString()); // 12:32:10
# Parameter Name Required Type Description
0 time Yes ms Time to wait in milliseconds
Return Type
Promise<unknown> Promise that resolves after the given time

[↑ Back to waiters ↑]

waitUntil

waitUntil(time: ms): Promise<null>
waiters.waitUntil(time: ms): Promise<null>

Accurate (pinged) wait until given time

import { waitUntil } from 'swiss-ak';

console.log(new Date().toTimeString()); // 12:30:10
await waitUntil(Date.now() + minutes(10));
console.log(new Date().toTimeString()); // 12:40:10
# Parameter Name Required Type Description
0 time Yes ms Unix time to wait until
Return Type
Promise<null> Promise that resolves at the given time

[↑ Back to waiters ↑]

waitFor

waitFor(time: ms): Promise<null>
waiters.waitFor(time: ms): Promise<null>

Accurate (pinged) wait the given ms

import { waitFor } from 'swiss-ak';

console.log(new Date().toTimeString()); // 12:30:10
await waitFor(minutes(5));
console.log(new Date().toTimeString()); // 12:35:10
# Parameter Name Required Type Description
0 time Yes ms Time to wait in milliseconds
Return Type
Promise<null> Promise that resolves after the given time

[↑ Back to waiters ↑]

waitEvery

waitEvery(timing: ms, offset: ms): Promise<null>
waiters.waitEvery(timing: ms, offset: ms): Promise<null>

Accurate (pinged) wait for next 'every X' event

import { waitEvery } from 'swiss-ak';

console.log(new Date().toTimeString()); // 12:30:10
await waitEvery(hours(2));
console.log(new Date().toTimeString()); // 14:00:00
# Parameter Name Required Type Description
0 timing Yes ms Timing period in milliseconds
1 offset No ms Offset in milliseconds
Return Type
Promise<null> Promise that resolves at the next 'every X' event

[↑ Back to waiters ↑]

stopInterval

stopInterval(intID: number): void
waiters.stopInterval(intID: number): void
import { interval, stopInterval } from 'swiss-ak';

console.log(new Date().toTimeString()); // 12:30:10
interval((intID, count) => {
  console.log(new Date().toTimeString()); // 13:00:00, 14:00:00, 15:00:00
  if (count === 3) {
    stopInterval(intID);
  }
}, hours(1));
# Parameter Name Required Type Description
0 intID Yes number Interval ID
Return Type
void

[↑ Back to waiters ↑]

interval

interval(action: (intID?: number, count?: number) => any, timing: ms): number
waiters.interval(action: (intID?: number, count?: number) => any, timing: ms): number

Accurate (pinged) interval for every 'every X' event

import { interval, stopInterval } from 'swiss-ak';

console.log(new Date().toTimeString()); // 12:30:10
interval((intID, count) => {
  console.log(new Date().toTimeString()); // 13:00:00, 14:00:00, 15:00:00
  if (count === 3) {
    stopInterval(intID);
  }
}, hours(1));
# Parameter Name Required Type Description
0 action Yes (intID?: number, count?: number) => any Action to run on each interval
1 timing Yes ms Timing period in milliseconds
Return Type
number Interval ID

[↑ Back to waiters ↑]

fn

A collection of useful higher-order functions.

[↑ Back to top ↑]

noop

fn.noop(): void

No operation. Do nothing, return nothing.

const run = condition ? doSomething : fn.noop;
run();
Return Type
void

[↑ Back to fn ↑]

noact

fn.noact(item: T): T

No action. Returns the first argument it receives.

const items = stuff
  .map(condition ? mapSomething : fn.noact)
# Parameter Name Required Type Description
0 item No T Item to return
Return Type
T The first argument it receives

[↑ Back to fn ↑]

result

fn.result(item: T): () => T

Returns a function that returns the first argument.

const items = stuff
  .filter(condition ? mapSomething : fn.result(true))
# Parameter Name Required Type Description
0 item No T Item to return from the function
Return Type
() => T Function that returns the first argument

[↑ Back to fn ↑]

resolve

fn.resolve(item: T): () => Promise<T>

Returns an async function that resolves to the first argument

Like fn.result, but wrapped in a Promise

await Promise.all(stuff.map(fn.resolve()));
# Parameter Name Required Type Description
0 item No T Item to resolve
Return Type
() => Promise<T> Function that returns a Promise that resolves to the first argument

[↑ Back to fn ↑]

reject

fn.reject(item: T): () => Promise<T>

Returns an async function that rejects with the first argument

await Promise.all(stuff.map(fn.reject()));
# Parameter Name Required Type Description
0 item No T Item to reject
Return Type
() => Promise<T> Function that returns a Promise that rejects with the first argument

[↑ Back to fn ↑]

filters

fn.filters;

Collection of functions that can be used with Array.filter

[↑ Back to fn ↑]

exists

fn.exists(item: T): boolean
fn.filters.exists(item: T): boolean
filters.exists(item: T): boolean

Returns true if item isn't null or undefined.

[null, 1, undefined, 2].filter(fn.exists); // [1, 2]
# Parameter Name Required Type Description
0 item Yes T Item to check if it exists
Return Type
boolean True if item isn't null or undefined

[↑ Back to fn ↑]

isTruthy

fn.isTruthy(item: T): boolean
fn.filters.isTruthy(item: T): boolean
filters.isTruthy(item: T): boolean

Returns true if item is truthy.

[0, 1, 2].filter(fn.isTruthy); // [1, 2]
['', 'a', 'b'].filter(fn.isTruthy); // ['a', 'b']
# Parameter Name Required Type Description
0 item Yes T Item to check if it is truthy
Return Type
boolean True if item is truthy

[↑ Back to fn ↑]

isFalsy

fn.isFalsy(item: T): boolean
fn.filters.isFalsy(item: T): boolean
filters.isFalsy(item: T): boolean

Returns true if item is falsy.

[0, 1, 2].filter(fn.isFalsy); // [0]
['', 'a', 'b'].filter(fn.isFalsy); // ['']
# Parameter Name Required Type Description
0 item Yes T Item to check if it is falsy
Return Type
boolean True if item is falsy

[↑ Back to fn ↑]

isEmpty

fn.isEmpty(item: T[] | string): boolean
fn.filters.isEmpty(item: T[] | string): boolean
filters.isEmpty(item: T[] | string): boolean

Returns true if item's length is 0

['', 'a', 'b'].filter(fn.isEmpty); // ['']
[[], [1], [2]].filter(fn.isEmpty); // [[]]
# Parameter Name Required Type Description
0 item Yes T[] | string Item to check if it is empty
Return Type
boolean True if item's length is 0

[↑ Back to fn ↑]

isNotEmpty

fn.isNotEmpty(item: T[] | string): boolean
fn.filters.isNotEmpty(item: T[] | string): boolean
filters.isNotEmpty(item: T[] | string): boolean

Returns true if item's length is 1 or more

['', 'a', 'b'].filter(fn.isNotEmpty); // ['a', 'b']
[[], [1], [2]].filter(fn.isNotEmpty); // [[1], [2]]
# Parameter Name Required Type Description
0 item Yes T[] | string Item to check if it is not empty
Return Type
boolean True if item's length is 1 or more

[↑ Back to fn ↑]

isEqual

fn.isEqual(item: T): (other: T) => boolean
fn.filters.isEqual(item: T): (other: T) => boolean
filters.isEqual(item: T): (other: T) => boolean

Returns a function that returns true if the item is equal to provided value.

[0, 1, 2].filter(fn.isEqual(1)); // [1]
# Parameter Name Required Type Description
0 item Yes T Item to check whether each item of the array is equal to
Return Type
(other: T) => boolean Function to use in Array.filter

[↑ Back to fn ↑]

isNotEqual

fn.isNotEqual(item: T): (other: T) => boolean
fn.filters.isNotEqual(item: T): (other: T) => boolean
filters.isNotEqual(item: T): (other: T) => boolean

Returns a function that returns true if the item is not equal to provided value.

[0, 1, 2].filter(fn.isNotEqual(1)); // [0, 2]
# Parameter Name Required Type Description
0 item Yes T Item to check whether each item of the array is not equal to
Return Type
(other: T) => boolean Function to use in Array.filter

[↑ Back to fn ↑]

dedupe

fn.dedupe(item: T, index: number, array: T[]): boolean
fn.filters.dedupe(item: T, index: number, array: T[]): boolean
filters.dedupe(item: T, index: number, array: T[]): boolean

Removes duplicate items from an array.

[0, 1, 2, 1, 0].filter(fn.dedupe); // [0, 1, 2]
# Parameter Name Required Type Description
0 item Yes T Given item in array
1 index Yes number Index of the given item
2 array Yes T[] Array of items
Return Type
boolean True if the item is the first occurrence in the array

[↑ Back to fn ↑]

dedupeMapped

fn.dedupeMapped(mapFn: (value?: T, index?: number, array?: T[]) => U): (item: T, index: number, array: T[]) => boolean
fn.filters.dedupeMapped(mapFn: (value?: T, index?: number, array?: T[]) => U): (item: T, index: number, array: T[]) => boolean
filters.dedupeMapped(mapFn: (value?: T, index?: number, array?: T[]) => U): (item: T, index: number, array: T[]) => boolean

Removes duplicate items from an array based on a mapped value.

[2, 4, 6, 8, 10, 12].filter(fn.dedupeMapped((v) => v % 3)); // [ 2, 4, 6 ] (maps to [ 2, 1, 0, 2, 1, 0 ])
# Parameter Name Required Type Description
0 mapFn Yes (value?: T, index?: number, array?: T[]) => U Function to map the item to a new value (will be used to check for duplicates)
Return Type
(item: T, index: number, array: T[]) => boolean Function to use in Array.filter

[↑ Back to fn ↑]

maps

fn.maps;

Collection of functions that can be used with Array.map

[↑ Back to fn ↑]

toString

fn.toString(item: T): string
fn.maps.toString(item: T): string
maps.toString(item: T): string

Maps the item to a string.

[0, 1, 2].map(fn.toString); // ['0', '1', '2']
# Parameter Name Required Type Description
0 item Yes T Item in an array
Return Type
string String of the item

[↑ Back to fn ↑]

toNumber

fn.toNumber(item: T): number
fn.maps.toNumber(item: T): number
maps.toNumber(item: T): number

Maps the item to a number.

['0', '1', '2'].map(fn.toNumber); // [0, 1, 2]
# Parameter Name Required Type Description
0 item Yes T Item in an array
Return Type
number Number of the item

[↑ Back to fn ↑]

toBool

fn.toBool(item: T): boolean
fn.maps.toBool(item: T): boolean
maps.toBool(item: T): boolean

Maps the item to a boolean.

[0, 1, 2].map(fn.toBool); // [false, true, true]
['true', 'false', '', 'text'].map(fn.toBool); // [true, false, false, true]
# Parameter Name Required Type Description
0 item Yes T Item in an array
Return Type
boolean Boolean of the item

[↑ Back to fn ↑]

toProp

fn.toProp(propName: keyof O): (item: O) => O[keyof O]
fn.maps.toProp(propName: keyof O): (item: O) => O[keyof O]
maps.toProp(propName: keyof O): (item: O) => O[keyof O]

Maps the item to a given property of the item

[{name: 'Jack'}, {name: 'Jill'}].map(fn.toProp('name')); // ['Jack', 'Jill']
# Parameter Name Required Type Description
0 propName Yes keyof O Property to get from each item
Return Type
(item: O) => O[keyof O] Function to use in Array.map

[↑ Back to fn ↑]

toFixed

fn.toFixed(precision: number): (num: number) => number
fn.maps.toFixed(precision: number): (num: number) => number
maps.toFixed(precision: number): (num: number) => number

Map the items (numbers) of an array to a fixed precision.

[1.234, 5.678, 9.012].map(fn.toFixed(2)); // [1.23, 5.68, 9.01]
# Parameter Name Required Type Description
0 precision Yes number Number of decimal places to round to
Return Type
(num: number) => number Function to use in Array.map

[↑ Back to fn ↑]

sorts

fn.sorts;

Collection of functions that can be used with Array.sort

[↑ Back to fn ↑]

asc

fn.asc(a: T, b: T): number
fn.sorts.asc(a: T, b: T): number
sorts.asc(a: T, b: T): number

Sort ascending.

[2, 4, 3, 1].sort(fn.asc); // [1, 2, 3, 4]
# Parameter Name Required Type Description
0 a Yes T Item to compare
1 b Yes T Item to compare
Return Type
number Number used for sorting

[↑ Back to fn ↑]

desc

fn.desc(a: T, b: T): number
fn.sorts.desc(a: T, b: T): number
sorts.desc(a: T, b: T): number

Sort descending.

[2, 4, 3, 1].sort(fn.desc); // [4, 3, 2, 1]
# Parameter Name Required Type Description
0 a Yes T Item to compare
1 b Yes T Item to compare
Return Type
number Number used for sorting

[↑ Back to fn ↑]

byProp

fn.byProp(propName: keyof O, sortFn: SortFn<O[keyof O]>): SortFn<O>
fn.sorts.byProp(propName: keyof O, sortFn: SortFn<O[keyof O]>): SortFn<O>
sorts.byProp(propName: keyof O, sortFn: SortFn<O[keyof O]>): SortFn<O>

Sort by a given property.

const people = [{age: 2}, {age: 4}, {age: 3}, {age: 1}];
people.sort(fn.byProp('age', fn.asc)); // [{age: 1}, {age: 2}, {age: 3}, {age: 4}]
# Parameter Name Required Type Default Description
0 propName Yes keyof O Property to sort by
1 sortFn No SortFn<O[keyof O]> fn.sorts.asc Sort function to use
Return Type
SortFn<O> Function to use in Array.sort

[↑ Back to fn ↑]

nearestTo

fn.nearestTo(target: number | `${number}`): (a: number | `${number}`, b: number | `${number}`) => number
fn.sorts.nearestTo(target: number | `${number}`): (a: number | `${number}`, b: number | `${number}`) => number
sorts.nearestTo(target: number | `${number}`): (a: number | `${number}`, b: number | `${number}`) => number

Sort by the nearest value to the given value.

Values get converted to numbers before comparison.

const people = [2, 4, 3, 1];
people.sort(fn.nearestTo(3)); // [3, 2, 4, 1]
# Parameter Name Required Type Description
0 target Yes number | `${number}` Target value to sort by
Return Type
(a: number | `${number}`, b: number | `${number}`) => number Function to use in Array.sort

[↑ Back to fn ↑]

furthestFrom

fn.furthestFrom(target: number | `${number}`): (a: number | `${number}`, b: number | `${number}`) => number
fn.sorts.furthestFrom(target: number | `${number}`): (a: number | `${number}`, b: number | `${number}`) => number
sorts.furthestFrom(target: number | `${number}`): (a: number | `${number}`, b: number | `${number}`) => number

Sort by the furthest value to the given value.

const people = [2, 4, 3, 1];
people.sort(fn.furthestFrom(3)); // [1, 2, 4, 3]
# Parameter Name Required Type Description
0 target Yes number | `${number}` Target value to sort by
Return Type
(a: number | `${number}`, b: number | `${number}`) => number Function to use in Array.sort

[↑ Back to fn ↑]

array

fn.array(sortFn: SortFn<T>): (a: T[], b: T[]) => number
fn.sorts.array(sortFn: SortFn<T>): (a: T[], b: T[]) => number
sorts.array(sortFn: SortFn<T>): (a: T[], b: T[]) => number

Sort an array of arrays by the given sort function.

Sorts by the first item in the array, then the second, etc. until a non-zero result is found.

const arr = [[1, 2], [3, 4], [5, 6]];
arr.sort(fn.array(fn.asc)); // [[1, 2], [3, 4], [5, 6]]
# Parameter Name Required Type Default Description
0 sortFn No SortFn<T> fn.sorts.asc Sort function to use
Return Type
(a: T[], b: T[]) => number Function to use in Array.sort

[↑ Back to fn ↑]

arrayAsc

fn.arrayAsc(a: T, b: T): number
fn.sorts.arrayAsc(a: T, b: T): number
sorts.arrayAsc(a: T, b: T): number

Sort an array of arrays in ascending order

Sorts by the first item in the array, then the second, etc. until a non-zero result is found.

const arr = [[1, 2], [3, 4], [5, 6]];
arr.sort(fn.arrayAsc); // [[1, 2], [3, 4], [5, 6]]
# Parameter Name Required Type Description
0 a Yes T Item to compare
1 b Yes T Item to compare
Return Type
number Number used for sorting

[↑ Back to fn ↑]

arrayDesc

fn.arrayDesc(a: T, b: T): number
fn.sorts.arrayDesc(a: T, b: T): number
sorts.arrayDesc(a: T, b: T): number

Sort an array of arrays in descending order

Sorts by the first item in the array, then the second, etc. until a non-zero result is found.

const arr = [[1, 2], [3, 4], [5, 6]];
arr.sort(fn.arrayDesc); // [[5, 6], [3, 4], [1, 2]]
# Parameter Name Required Type Description
0 a Yes T Item to compare
1 b Yes T Item to compare
Return Type
number Number used for sorting

[↑ Back to fn ↑]

reduces

fn.reduces;

Collection of functions that can be used with Array.reduce

[↑ Back to fn ↑]

combine

fn.combine(a: T, b: T): T
fn.reduces.combine(a: T, b: T): T
reduces.combine(a: T, b: T): T

Adds or concats the items

[1, 2, 3].reduce(fn.combine); // 6
['a', 'b', 'c'].reduce(fn.combine); // 'abc'
# Parameter Name Required Type Description
0 a Yes T Item to combine
1 b Yes T Item to combine
Return Type
T Combined item

[↑ Back to fn ↑]

combineProp

fn.combineProp(propName: keyof O): (a: O[keyof O], b: O) => O[keyof O]
fn.reduces.combineProp(propName: keyof O): (a: O[keyof O], b: O) => O[keyof O]
reduces.combineProp(propName: keyof O): (a: O[keyof O], b: O) => O[keyof O]

Adds or concats the given property of the items

Note: The initial value is required, because the first item is not yet an object.

const people = [{name: 'a', age: 1}, {name: 'b', age: 2}, {name: 'c', age: 3}];
people.reduce(fn.combineProp('age'), 0); // 6
people.reduce(fn.combineProp('name'), ''); // 'abc'
# Parameter Name Required Type Description
0 propName Yes keyof O Property to combine
Return Type
(a: O[keyof O], b: O) => O[keyof O] Function to use in Array.reduce

[↑ Back to fn ↑]

mode

fn.mode(prev: T, curr: T, index: number, arr: T[]): T
fn.reduces.mode(prev: T, curr: T, index: number, arr: T[]): T
reduces.mode(prev: T, curr: T, index: number, arr: T[]): T

Returns the most common value in an array.

[1, 2, 3, 2, 1, 1].reduce(fn.mode); // 1
# Parameter Name Required Type Description
0 prev Yes T Previous value
1 curr Yes T Current value
2 index Yes number Index of the current value
3 arr Yes T[] Array of values
Return Type
T Most common value so far

[↑ Back to fn ↑]

modeMapped

fn.modeMapped(mapFn: (value: T, index: number, array: T[]) => U): (prev: T, curr: T, index: number, arr: T[]) => T
fn.reduces.modeMapped(mapFn: (value: T, index: number, array: T[]) => U): (prev: T, curr: T, index: number, arr: T[]) => T
reduces.modeMapped(mapFn: (value: T, index: number, array: T[]) => U): (prev: T, curr: T, index: number, arr: T[]) => T

Returns the most common value in an array, based on a given map function.

[2, 4, 6, 8, 9, 12].reduce(fn.modeMapped((v) => v % 3)); // 6 (maps to [ 2, 1, 0, 2, 0, 0 ])
# Parameter Name Required Type Description
0 mapFn Yes (value: T, index: number, array: T[]) => U Map function to use
Return Type
(prev: T, curr: T, index: number, arr: T[]) => T Function to use in Array.reduce

[↑ Back to fn ↑]

everys

fn.everys;

Collection of functions that can be used with Array.every

[↑ Back to fn ↑]

isAllEqual

fn.isAllEqual(val: T, i: number, arr: T[]): boolean
fn.everys.isAllEqual(val: T, i: number, arr: T[]): boolean
everys.isAllEqual(val: T, i: number, arr: T[]): boolean

Returns if all the items are equal to one another.

[1, 1, 1].every(fn.isAllEqual); // true
[1, 2, 1].every(fn.isAllEqual); // false
# Parameter Name Required Type Description
0 val Yes T Value to check
1 i Yes number Index of the value
2 arr Yes T[] Array of values
Return Type
boolean True if all the items are equal to one another so far

[↑ Back to fn ↑]

isUnique

fn.isUnique(val: T, i: number, arr: T[]): boolean
fn.everys.isUnique(val: T, i: number, arr: T[]): boolean
everys.isUnique(val: T, i: number, arr: T[]): boolean

Returns true if the item is unique in the array.

[1, 1, 1].every(fn.isUnique); // false
[1, 2, 1].every(fn.isUnique); // false
[1, 2, 3].every(fn.isUnique); // true
# Parameter Name Required Type Description
0 val Yes T Value to check
1 i Yes number Index of the value
2 arr Yes T[] Array of values
Return Type
boolean True if the item is unique in the array so far

[↑ Back to fn ↑]

groups

fn.groups;

Collection of functions that can be used with ArrayTools.group

[↑ Back to fn ↑]

bySize

fn.bySize(size: number): (value: T, index: number, array: T[]) => number
fn.groups.bySize(size: number): (value: T, index: number, array: T[]) => number
groups.bySize(size: number): (value: T, index: number, array: T[]) => number

Group an array into groups of a given size.

Note: The last group may be smaller than the given size.

Note: The groups a distributed in order, so the first group will be filled up first, then the next, etc.

Note: Consider using ArrayTools.partition instead

const nums = [1, 2, 3, 4, 5, 6, 7, 8];
ArrayTools.group(nums, fn.bySize(3)); // [[1, 2, 3], [4, 5, 6], [7, 8]]
# Parameter Name Required Type Description
0 size Yes number Size of the groups
Return Type
(value: T, index: number, array: T[]) => number Function to use in ArrayTools.group

[↑ Back to fn ↑]

byNumGroups

fn.byNumGroups(numGroups: number): (value: T, index: number, array: T[]) => any
fn.groups.byNumGroups(numGroups: number): (value: T, index: number, array: T[]) => any
groups.byNumGroups(numGroups: number): (value: T, index: number, array: T[]) => any

Group an array into a certain number of groups as evenly as possible.

Note: The groups are distributed in order, so the first group will be filled up first, then the next, etc.

const nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
ArrayTools.group(nums, fn.byNumGroups(3)); // [[1, 2, 3, 4], [5, 6, 7], [8, 9, 10]]
# Parameter Name Required Type Description
0 numGroups Yes number Number of groups to create
Return Type
(value: T, index: number, array: T[]) => any Function to use in ArrayTools.group

[↑ Back to fn ↑]

ArrayTools

A collection of useful array functions.

[↑ Back to top ↑]

create

create(length: number, value: T): T[]
ArrayTools.create(length: number, value: T): T[]

Create an array of the given length, where each value is the given value

ArrayTools.create(3); // [ 1, 1, 1 ]
ArrayTools.create(3, 'a'); // [ 'a', 'a', 'a' ]
ArrayTools.create(3, 1); // [ 1, 1, 1 ]
# Parameter Name Required Type Default Description
0 length No number 1 Length of the array to create
1 value No T 1 as unknown as T Value to fill the array with
Return Type
T[] Array of the given length, full of the given value

[↑ Back to ArrayTools ↑]

filled

filled(length: number, value: T): T[]
ArrayTools.filled(length: number, value: T): T[]

Create an array of the given length, where each value is the given value

ArrayTools.filled(3); // [ 1, 1, 1 ]
ArrayTools.filled(3, 'a'); // [ 'a', 'a', 'a' ]
ArrayTools.filled(3, 1); // [ 1, 1, 1 ]
# Parameter Name Required Type Default Description
0 length No number 1 Length of the array to create
1 value Yes T Value to fill the array with
Return Type
T[] Array of the given length, full of the given value

[↑ Back to ArrayTools ↑]

range

range(length: number, multiplier: number, offset: number): number[]
ArrayTools.range(length: number, multiplier: number, offset: number): number[]

Returns an array of the given length, where each value is equal to it's index e.g. [0, 1, 2, ..., length]

ArrayTools.range(3);  // [0, 1, 2]
ArrayTools.range(5);  // [0, 1, 2, 3, 4]
ArrayTools.range(10); // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

ArrayTools.range(3, 2);  // [0, 2, 4]
ArrayTools.range(5, 2);  // [0, 2, 4, 6, 8]
ArrayTools.range(10, 10); // [0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
# Parameter Name Required Type Default Description
0 length No number 1 Length of the array to create
1 multiplier No number 1 Multiplier to apply to each value
2 offset No number 0 Offset to apply to each value (after the multiplier)
Return Type
number[] Array of the given length, where each value is equal to it's index

[↑ Back to ArrayTools ↑]

zip

zip(...arrs: T[]): ZippedArrays<T>[]
ArrayTools.zip(...arrs: T[]): ZippedArrays<T>[]

Converts multiple arrays into an array of 'tuples' for each value at the corresponding indexes.

Limited to the length of the shortest provided array

Inspired by python's 'zip'

ArrayTools.zip([1, 2, 3, 4], ['a', 'b', 'c']); // [ [1, 'a'], [2, 'b'], [3, 'c'] ]
# Parameter Name Required Type Description
0… arrs No T[] Arrays to zip together
Return Type
ZippedArrays<T>[] Array of 'tuples' for each value at the corresponding indexes

[↑ Back to ArrayTools ↑]

zipMax

zipMax(...arrs: T[]): ZippedArrays<T>[]
ArrayTools.zipMax(...arrs: T[]): ZippedArrays<T>[]

Converts multiple arrays into an array of 'tuples' for each value at the corresponding indexes.

Unlike zip, it will match the length of the longest provided array, filling in any missing values with undefined

Inspired by python's 'zip'

ArrayTools.zipMax([1, 2, 3, 4], ['a', 'b', 'c']); //[ [ 1, 'a' ], [ 2, 'b' ], [ 3, 'c' ], [ 4, undefined ] ]
# Parameter Name Required Type Description
0… arrs No T[] Arrays to zip together
Return Type
ZippedArrays<T>[] Array of 'tuples' for each value at the corresponding indexes

[↑ Back to ArrayTools ↑]

sortByMapped

sortByMapped(arr: T[], mapFn: (value: T, index: number, array: T[]) => M, sortFn: (a: M, b: M) => number): T[]
ArrayTools.sortByMapped(arr: T[], mapFn: (value: T, index: number, array: T[]) => M, sortFn: (a: M, b: M) => number): T[]

Sort an array by a mapped form of the values, but returning the initial values

ArrayTools.sortByMapped(['2p', '3p', '1p'], (v) => Number(v.replace('p', ''))); // ['1p', '2p', '3p']
ArrayTools.sortByMapped(
  ['2p', '3p', '1p'],
  (v) => Number(v.replace('p', '')),
  (a, b) => b - a
); // ['3p', '2p', '1p']
# Parameter Name Required Type Default Description
0 arr Yes T[] Array to sort
1 mapFn Yes (value: T, index: number, array: T[]) => M Function to map the values to
2 sortFn No (a: M, b: M) => number fn.asc Function to sort the mapped values by
Return Type
T[] Sorted array (non-mutated)

[↑ Back to ArrayTools ↑]

randomise

randomise(arr: T[]): T[]
ArrayTools.randomise(arr: T[]): T[]

Returns a clone of the provided array with it's items in a random order

ArrayTools.randomise([1, 2, 3, 4, 5, 6]); // [ 5, 3, 4, 1, 2, 6 ]
ArrayTools.randomise([1, 2, 3, 4, 5, 6]); // [ 5, 1, 3, 2, 4, 6 ]
ArrayTools.randomise([1, 2, 3, 4, 5, 6]); // [ 6, 1, 4, 5, 2, 3 ]
ArrayTools.randomise([1, 2, 3, 4, 5, 6]); // [ 1, 4, 5, 2, 3, 6 ]
ArrayTools.randomise([1, 2, 3, 4, 5, 6]); // [ 2, 6, 1, 3, 4, 5 ]
# Parameter Name Required Type Description
0 arr Yes T[] Array to randomise
Return Type
T[] Randomised array (non-mutated)

[↑ Back to ArrayTools ↑]

reverse

reverse(arr: T[]): T[]
ArrayTools.reverse(arr: T[]): T[]

Returns a new array with the order reversed without affecting original array

const arr1 = [1, 2, 3];
arr1            // [1, 2, 3]
arr1.reverse(); // [3, 2, 1]
arr1            // [3, 2, 1] - mutated

const arr2 = [1, 2, 3];
arr2            // [1, 2, 3]
ArrayTools.reverse(arr2);  // [3, 2, 1]
arr2            // [1, 2, 3] - not mutated
# Parameter Name Required Type Description
0 arr Yes T[] Array to reverse
Return Type
T[] Reversed array (non-mutated)

[↑ Back to ArrayTools ↑]

entries

entries(arr: T[]): [number, T][]
ArrayTools.entries(arr: T[]): [number, T][]

Returns array of 'tuples' of index/value pairs

const arr = ['a', 'b', 'c'];
ArrayTools.entries(arr); // [ [0, 'a'], [1, 'b'], [2, 'c'] ]

for (let [index, value] of ArrayTools.entries(arr)) {
 console.log(index); // 0, 1, 2
 console.log(value); // 'a', 'b', 'c'
}
# Parameter Name Required Type Description
0 arr Yes T[] Array to get entries from
Return Type
[number, T][] Array of 'tuples' of index/value pairs

[↑ Back to ArrayTools ↑]

repeat

repeat(maxLength: number, ...items: T[]): T[]
ArrayTools.repeat(maxLength: number, ...items: T[]): T[]

Returns an array with the given items repeated

ArrayTools.repeat(5, 'a'); // [ 'a', 'a', 'a', 'a', 'a' ]
ArrayTools.repeat(5, 'a', 'b'); // [ 'a', 'b', 'a', 'b', 'a' ]
# Parameter Name Required Type Description
0 maxLength Yes number Maximum length of the array
1… items No T[] Items to repeat
Return Type
T[] Array with the given items repeated

[↑ Back to ArrayTools ↑]

roll

roll(distance: number, arr: T[]): T[]
ArrayTools.roll(distance: number, arr: T[]): T[]

'Roll' the array by a given amount so that is has a new first item. Length and contents remain the same, but the order is changed

ArrayTools.roll(1, [0, 1, 2, 3, 4, 5, 6, 7]); // [ 1, 2, 3, 4, 5, 6, 7, 0 ]
ArrayTools.roll(4, [0, 1, 2, 3, 4, 5, 6, 7]); // [ 4, 5, 6, 7, 0, 1, 2, 3 ]
# Parameter Name Required Type Description
0 distance Yes number Distance to roll the array by
1 arr Yes T[] Array to roll
Return Type
T[] Rolled array (non-mutated)

[↑ Back to ArrayTools ↑]

sortNumberedText

sortNumberedText(texts: string[], ignoreCase: boolean): string[]
ArrayTools.sortNumberedText(texts: string[], ignoreCase: boolean): string[]

Alphabetically sorts a list of strings, but keeps multi-digit numbers in numerical order (rather than alphabetical)

const names = ['name1', 'name10', 'name2', 'foo20', 'foo10', 'foo9'];
names.sort(); // [ 'foo10', 'foo20', 'foo9', 'name1', 'name10', 'name2' ]
ArrayTools.sortNumberedText(names); // [ 'foo9', 'foo10', 'foo20', 'name1', 'name2', 'name10' ]
# Parameter Name Required Type Default Description
0 texts Yes string[] Texts to sort
1 ignoreCase No boolean true Whether to ignore case when sorting
Return Type
string[] Sorted array (non-mutated)

[↑ Back to ArrayTools ↑]

partition

partition(array: T[], partitionSize: number): T[][]
ArrayTools.partition(array: T[], partitionSize: number): T[][]

Breaks an array into smaller arrays of a given size

ArrayTools.partition([1, 2, 3, 4], 3); // [ [ 1, 2, 3 ], [ 4 ] ]

ArrayTools.partition([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 3); // [ [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ], [ 10 ] ]
ArrayTools.partition([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 4); // [ [ 1, 2, 3, 4 ], [ 5, 6, 7, 8 ], [ 9, 10 ] ]
ArrayTools.partition([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 5); // [ [ 1, 2, 3, 4, 5 ], [ 6, 7, 8, 9, 10 ] ]
# Parameter Name Required Type Default Description
0 array Yes T[] Array to partition
1 partitionSize No number Math.ceil(array.length / 2) Size of each partition
Return Type
T[][] Array of arrays, each containing a partition of the original array

[↑ Back to ArrayTools ↑]

partitionEvenly

partitionEvenly(array: T[], maxPartitionSize: number): T[][]
ArrayTools.partitionEvenly(array: T[], maxPartitionSize: number): T[][]

Breaks an array into smaller arrays of a given size, but tries to keep the sizes as even as possible

ArrayTools.partitionEvenly([1, 2, 3, 4], 3); // [ [ 1, 2 ], [ 3, 4 ] ]

ArrayTools.partitionEvenly([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 3); // [ [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8 ], [ 9, 10 ] ]
ArrayTools.partitionEvenly([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 4); // [ [ 1, 2, 3, 4 ], [ 5, 6, 7 ], [ 8, 9, 10 ] ]
ArrayTools.partitionEvenly([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 5); // [ [ 1, 2, 3, 4, 5 ], [ 6, 7, 8, 9, 10 ] ]
# Parameter Name Required Type Default Description
0 array Yes T[] Array to partition
1 maxPartitionSize No number Math.ceil(array.length / 2) Maximum size of each partition
Return Type
T[][] Array of arrays, each containing a partition of the original array

[↑ Back to ArrayTools ↑]

groupObj

groupObj(array: T[], mapFn: (item: T, index: number, arr: T[]) => string | number): { [id: string]: T[]; [id: number]: T[]; }
ArrayTools.groupObj(array: T[], mapFn: (item: T, index: number, arr: T[]) => string | number): { [id: string]: T[]; [id: number]: T[]; }

Group items from an array into an object of arrays, based on a given map function.

const arr = [
  { group: 1, name: 'a' },
  { group: 2, name: 'b' },
  { group: 1, name: 'c' },
];
ArrayTools.groupObj(arr, item => item.group); // {
//   1: [ { group: 1, name: 'a' }, { group: 1, name: 'c' } ],
//   2: [ { group: 2, name: 'b' } ]
// }
# Parameter Name Required Type Description
0 array Yes T[] Array to group
1 mapFn Yes (item: T, index: number, arr: T[]) => string | number Map function to get the group key for each item
Return Type
{ [id: string]: T[]; [id: number]: T[]; } Object with the group keys as keys, and the items as values

[↑ Back to ArrayTools ↑]

group

group(array: T[], mapFn: (item: T, index: number, arr: T[]) => string | number): T[][]
ArrayTools.group(array: T[], mapFn: (item: T, index: number, arr: T[]) => string | number): T[][]

Group items from an array into an array of arrays, based on a given map function.

const arr = [
  { group: 1, name: 'a' },
  { group: 2, name: 'b' },
  { group: 1, name: 'c' },
];
ArrayTools.group(arr, item => item.group); // [
//   [ { group: 1, name: 'a' }, { group: 1, name: 'c' } ],
//   [ { group: 2, name: 'b' } ]
// ]
# Parameter Name Required Type Description
0 array Yes T[] Array to group
1 mapFn Yes (item: T, index: number, arr: T[]) => string | number Map function to get the group key for each item
Return Type
T[][] Array of arrays, each containing a group of the original array

[↑ Back to ArrayTools ↑]

findAndRemove

ArrayTools.findAndRemove(array: T[], predicate: (item: T, index: number, arr: T[]) => any, ...insertItems: T[]): T

Find the first item in an array that matches a given predicate, and remove it from the array

Note: This function mutates the provided array

const arr = [1, 2, 3, 4, 5];
ArrayTools.findAndRemove(arr, (item) => item === 3); // 3
arr; // [1, 2, 4, 5]
# Parameter Name Required Type Description
0 array Yes T[] Array to mutate
1 predicate Yes (item: T, index: number, arr: T[]) => any Function that returns true/truthy if the item should be removed
2… insertItems No T[] Items to insert in place of the removed item
Return Type
T The removed item (undefined if not found)

[↑ Back to ArrayTools ↑]

findLastAndRemove

ArrayTools.findLastAndRemove(array: T[], predicate: (item: T, index: number, arr: T[]) => any, ...insertItems: T[]): T

Find the last item in an array that matches a given predicate, and remove it from the array

Note: This function mutates the provided array

const arr = [1, 2, 3, 4, 5];
ArrayTools.findLastAndRemove(arr, (item) => item === 3); // 3
arr; // [1, 2, 4, 5]
# Parameter Name Required Type Description
0 array Yes T[] Array to mutate
1 predicate Yes (item: T, index: number, arr: T[]) => any Function that returns true/truthy if the item should be removed
2… insertItems No T[] Items to insert in place of the removed item
Return Type
T The removed item (undefined if not found)

[↑ Back to ArrayTools ↑]

filterAndRemove

ArrayTools.filterAndRemove(array: T[], predicate: (item: T, index: number, arr: T[]) => any): T[]

Find the items in an array that matches a given predicate, and remove them from the array

Note: This function mutates the provided array

const arr = [1, 2, 3, 4, 5];
ArrayTools.filterAndRemove(arr, (item) => item === 3); // [3]
arr; // [1, 2, 4, 5]
# Parameter Name Required Type Description
0 array Yes T[] Array to mutate
1 predicate Yes (item: T, index: number, arr: T[]) => any Function that returns true/truthy if the item should be removed
Return Type
T[] The removed items

[↑ Back to ArrayTools ↑]

utils

ArrayTools.utils;

Small helper functions that may help, but aren't important enough to be in ArrayTools directly

[↑ Back to ArrayTools ↑]

isNumString

ArrayTools.utils.isNumString(text: string): boolean

Returns true if the given string is a number

ArrayTools.utils.isNumString('123'); // true
ArrayTools.utils.isNumString('123a'); // false
# Parameter Name Required Type Description
0 text Yes string Text to check if it is a number
Return Type
boolean True if the given string is a number

[↑ Back to ArrayTools ↑]

partitionNums

ArrayTools.utils.partitionNums(ignoreCase: boolean): (name: string) => (string | number)[]

Splits a string into an array of strings and numbers

ArrayTools.utils.partitionNums(true)('123a'); // [ '123', 'a' ]
ArrayTools.utils.partitionNums(false)('123a'); // [ '123', 'a' ]
# Parameter Name Required Type Description
0 ignoreCase Yes boolean Whether to ignore case
Return Type
(name: string) => (string | number)[] Function to split a string into array of strings & numbers

[↑ Back to ArrayTools ↑]

ObjectTools

A collection of functions for working with objects

[↑ Back to top ↑]

remodel

ObjectTools.remodel(obj: T, func: (entries: [string, V][]) => [string, W][]): O

Apply a function to the entries of an object

const input = {'foo': 2, 'bar': 1, 'baz': 4}
ObjectTools.remodel(input, (entries) => entries.filter(([k, v]) => v % 2 === 0)) // { foo: 2, baz: 4 }
# Parameter Name Required Type Description
0 obj Yes T Object to remodel
1 func Yes (entries: [string, V][]) => [string, W][] Function to apply to the entries array
Return Type
O Remodeled object

[↑ Back to ObjectTools ↑]

remodelEach

ObjectTools.remodelEach(obj: T, func: (entry: [string, Vi], index: number, entries: [string, Vi][]) => [string, Vo]): O

Apply a function to each of the entries of an object

Note: similar to ObjectTools.map, but the function parameters are different. Prefer ObjectTools.map where possible.

const input = {'foo': 2, 'bar': 1, 'baz': 4}
ObjectTools.remodelEach(input, ([k, v]) => [k, v * 2]) // { foo: 4, bar: 2, baz: 8 }
# Parameter Name Required Type Description
0 obj Yes T Object to remodel
1 func Yes (entry: [string, Vi], index: number, entries: [string, Vi][]) => [string, Vo] Function to apply to each of the entries
Return Type
O Remodeled object

[↑ Back to ObjectTools ↑]

map

ObjectTools.map(obj: T, func: (key: string, value: Vi, index: number) => [string, Vo]): any

Maps the keys and values of an object in a similar way to Array.map

ObjectTools.map({a: 1, b: 2, c: 3}, (key, value) => [key, key + value]); // {a: 'a1', b: 'b2', c: 'c3'}
# Parameter Name Required Type Description
0 obj Yes T Object to map
1 func Yes (key: string, value: Vi, index: number) => [string, Vo] Function to apply to each of the entries
Return Type
any Mapped object

[↑ Back to ObjectTools ↑]

mapValues

ObjectTools.mapValues(obj: T, func: (key: string, value: Vi, index: number) => Vo): any

Maps the values of an object in a similar way to Array.map

ObjectTools.map({a: 1, b: 2, c: 3}, (key, value) => key.repeat(value)); // {a: 'a', b: 'bb', c: 'ccc'}
# Parameter Name Required Type Description
0 obj Yes T Object to map
1 func Yes (key: string, value: Vi, index: number) => Vo Function to apply to each of the entries
Return Type
any Mapped object

[↑ Back to ObjectTools ↑]

mapKeys

ObjectTools.mapKeys(obj: T, func: (key: string, value: V, index: number) => string): T

Maps the values of an object in a similar way to Array.map

ObjectTools.map({a: 1, b: 2, c: 3}, (key, value) => key.repeat(value)); // {a: 1, bb: 2, ccc: 3}
# Parameter Name Required Type Description
0 obj Yes T Object to map
1 func Yes (key: string, value: V, index: number) => string Function to apply to each of the entries
Return Type
T Mapped object

[↑ Back to ObjectTools ↑]

filter

ObjectTools.filter(obj: T, func: (key: string, value: V, index: number) => boolean): O

Removes entries from an object based on a predicate function

ObjectTools.filter({a: 1, b: 2, c: 3}, (k, v) => v % 2 === 0) // { b: 2 }
# Parameter Name Required Type Description
0 obj Yes T Object to filter
1 func Yes (key: string, value: V, index: number) => boolean Function to apply to each of the entries
Return Type
O Filtered object

[↑ Back to ObjectTools ↑]

clean

ObjectTools.clean(obj: T): O

Removes properties with undefined values

ObjectTools.clean({a: 1, b: undefined, c: 3}) // { a: 1, c: 3 }
# Parameter Name Required Type Description
0 obj Yes T Object to clean
Return Type
O Cleaned object

[↑ Back to ObjectTools ↑]

invert

ObjectTools.invert(obj: T): O

Inverts the keys and values of an object

ObjectTools.invert({ a: 'foo', b: 'bar' }); // { foo: 'a', bar: 'b'}
# Parameter Name Required Type Description
0 obj Yes T Object to invert
Return Type
O Inverted object

[↑ Back to ObjectTools ↑]

StringTools

A collection of string utilities

[↑ Back to top ↑]

capitalise

StringTools.capitalise(input: string, forceRestToLowerCase: boolean): string

Capitalises the first letter of each word in a string

StringTools.capitalise('hello world'); // 'Hello World'
# Parameter Name Required Type Default Description
0 input No string '' String to capitalise
1 forceRestToLowerCase No boolean true Whether to force the rest of the string to lower case
Return Type
string Capitalised string

[↑ Back to StringTools ↑]

angloise

StringTools.angloise(input: string): string

Remove accents from a string

StringTools.angloise('éèêë'); // 'eeee'
# Parameter Name Required Type Description
0 input Yes string String to angloise
Return Type
string String with accents removed

[↑ Back to StringTools ↑]

clean

StringTools.clean(input: string): string

Remove accents and non alphanumerics from a string

StringTools.clean('éèêë_--ab0'); // 'eeeeab0'
# Parameter Name Required Type Default Description
0 input No string '' String to clean
Return Type
string Cleaned string

[↑ Back to StringTools ↑]

repeat

StringTools.repeat(maxLength: number, repeated: string): string

Repeat the given string n times

StringTools.repeat(5, '-') // '-----'
StringTools.repeat(1, '-') // '-'
StringTools.repeat(0, '-') // ''
StringTools.repeat(-1, '-') // ''
# Parameter Name Required Type Description
0 maxLength Yes number Maximum length of the string
1 repeated Yes string String to repeat
Return Type
string Repeated string

[↑ Back to StringTools ↑]

makeRegExpSafe

StringTools.makeRegExpSafe(text: string): string

Makes a string safe to use in a RegExp

const textWithSpecChars = '$^*+?.()|{}[]\\';
const longText = `A long line with ${textWithSpecChars} in it`; // 'A long line with $^*+?.()|{}[]\ in it'

const safeText = makeRegExpSafe(textWithSpecChars); // '\$\^\*\+\?\.\(\)\|\{\}\[\]\\'
const regex = new RegExp(safeText);
longText.replace(regex, 'foobar'); // 'A long line with foobar in it'

longText.replace(new RegExp(makeRegExpSafe(textWithSpecChars)), 'foobar'); // 'A long line with foobar in it'
# Parameter Name Required Type Description
0 text Yes string String to make safe for use in a RegExp
Return Type
string String safe for use in a RegExp

[↑ Back to StringTools ↑]

replaceAll

StringTools.replaceAll(text: string, searchValue: string | RegExp, replacer: string | ((substring: string, ...args: any[]) => string)): string

'Polyfill' replacement for String.prototype.replaceAll, but uses String.prototype.replace (better backwards compatibility)

Accepts a string or RegExp as the searchValue, and a string or function as the replacer.

const input = 'the quick brown fox jumps over the lazy dog';

StringTools.replaceAll(input, /A|E|I|O|U/i, (match) => match.toUpperCase()) // 'thE qUIck brOwn fOx jUmps OvEr thE lAzy dOg'
StringTools.replaceAll(input, /A|E|I|O|U/i, '#') // 'th# q##ck br#wn f#x j#mps #v#r th# l#zy d#g'
StringTools.replaceAll(input, 'o', (match) => match.toUpperCase()) // 'the quick brOwn fOx jumps Over the lazy dOg'
StringTools.replaceAll(input, 'o', '#') // 'the quick br#wn f#x jumps #ver the lazy d#g'
# Parameter Name Required Type Description
0 text Yes string String to replace in
1 searchValue Yes string | RegExp String or RegExp to search for
2 replacer Yes string | ((substring: string, ...args: any[]) => string) String or function to replace the search value with
Return Type
string String with the search value replaced

[↑ Back to StringTools ↑]

randomId

StringTools.randomId(prefix: string, suffix: string): string

Generate a random ID.

Provides a random string of 10 alphanumeric characters, with the option to prefix and/or suffix the string.

Note: This is a very simple random ID generator, and is not suitable for use in security contexts, and does not guarantee uniqueness.

StringTools.randomId(); // 'du9876optw'
StringTools.randomId(); // '7xf8kewrkf'
StringTools.randomId(); // 'bums15yb9n'
StringTools.randomId(); // '8tcl55y4u1'
StringTools.randomId(); // '41pxan1bog'
StringTools.randomId(); // '122pa9czh4'
StringTools.randomId(); // 'iu7xappxtz'

StringTools.randomId('foo-'); // 'foo-xpynpfiz06'
StringTools.randomId('', '-bar'); // 'dpyq3i2uwq-bar'
StringTools.randomId('foo-', '-bar'); // 'foo-wapluosnf6-bar'
# Parameter Name Required Type Default Description
0 prefix No string '' Prefix to add to the random ID
1 suffix No string '' Suffix to add to the random ID
Return Type
string Random ID

[↑ Back to StringTools ↑]

clx

clx(...args: ClxType[]): string
StringTools.clx(...args: ClxType[]): string

Composes a className from a list of strings, conditional objects and arrays.

Accepts the different ways of supplying classes in AngularJS (ng-class) and returns a single string (so suitable for React).

clx('hello') // 'hello'
clx('foo', 'bar') // 'foo bar'
clx('foo', conditionA && 'bar') // 'foo'
clx('abc', conditionB && 'def') // 'abc def'
clx({'lorem': conditionA, 'ipsum': conditionB}) // 'ipsum'
# Parameter Name Required Type Description
0… args No ClxType[] Classes (or objects/arrays to compose
Return Type
string Composed class name

[↑ Back to StringTools ↑]

Case Manipulators

toCamelCase

StringTools.toCamelCase(input: string | string[], capitaliseFirst: boolean): string
StringTools.fromSlugCase.toCamelCase(input: string | string[], capitaliseFirst: boolean): string
StringTools.fromSnakeCase.toCamelCase(input: string | string[], capitaliseFirst: boolean): string
StringTools.fromSpaced.toCamelCase(input: string | string[], capitaliseFirst: boolean): string
StringTools.fromCamelCase.toCamelCase(input: string | string[], capitaliseFirst: boolean): string

Convert a string to camel case (e.g. thisIsCamelCase)

# Parameter Name Required Type Default Description
0 input Yes string | string[] String or array of strings to convert
1 capitaliseFirst No boolean false Whether to capitalise the first letter
Return Type
string Camel case string

[↑ Back to StringTools ↑]

toLowerCamelCase

StringTools.toLowerCamelCase(input: string | string[]): string
StringTools.fromSlugCase.toLowerCamelCase(input: string | string[]): string
StringTools.fromSnakeCase.toLowerCamelCase(input: string | string[]): string
StringTools.fromSpaced.toLowerCamelCase(input: string | string[]): string
StringTools.fromCamelCase.toLowerCamelCase(input: string | string[]): string

Convert a string to lower camel case (e.g. thisIsLowerCamelCase)

# Parameter Name Required Type Description
0 input Yes string | string[] String or array of strings to convert
Return Type
string Lower camel case string

[↑ Back to StringTools ↑]

toUpperCamelCase

StringTools.toUpperCamelCase(input: string | string[]): string
StringTools.fromSlugCase.toUpperCamelCase(input: string | string[]): string
StringTools.fromSnakeCase.toUpperCamelCase(input: string | string[]): string
StringTools.fromSpaced.toUpperCamelCase(input: string | string[]): string
StringTools.fromCamelCase.toUpperCamelCase(input: string | string[]): string

Convert a string to upper camel case (e.g. ThisIsLowerCamelCase)

# Parameter Name Required Type Description
0 input Yes string | string[] String or array of strings to convert
Return Type
string Upper camel case string

[↑ Back to StringTools ↑]

toCharacterSeparated

StringTools.toCharacterSeparated(input: string | string[], char: string, toUpper: boolean): string
StringTools.fromSlugCase.toCharacterSeparated(input: string | string[], char: string, toUpper: boolean): string
StringTools.fromSnakeCase.toCharacterSeparated(input: string | string[], char: string, toUpper: boolean): string
StringTools.fromSpaced.toCharacterSeparated(input: string | string[], char: string, toUpper: boolean): string
StringTools.fromCamelCase.toCharacterSeparated(input: string | string[], char: string, toUpper: boolean): string

Convert a string to text where words are separated by a given character (e.g. this#is#character#separated)

# Parameter Name Required Type Default Description
0 input Yes string | string[] String or array of strings to convert
1 char No string ',' Character to separate the words by
2 toUpper No boolean false Whether to convert the words to upper case
Return Type
string Character separated string

[↑ Back to StringTools ↑]

toSlugCase

StringTools.toSlugCase(input: string | string[], toUpper: boolean): string
StringTools.fromSlugCase.toSlugCase(input: string | string[], toUpper: boolean): string
StringTools.fromSnakeCase.toSlugCase(input: string | string[], toUpper: boolean): string
StringTools.fromSpaced.toSlugCase(input: string | string[], toUpper: boolean): string
StringTools.fromCamelCase.toSlugCase(input: string | string[], toUpper: boolean): string

Convert a string to camel case (e.g. this-is-slug-case)

# Parameter Name Required Type Default Description
0 input Yes string | string[] String or array of strings to convert
1 toUpper No boolean false Whether to convert the words to upper case
Return Type
string Slug case string

[↑ Back to StringTools ↑]

toLowerSlugCase

StringTools.toLowerSlugCase(input: string | string[]): string
StringTools.fromSlugCase.toLowerSlugCase(input: string | string[]): string
StringTools.fromSnakeCase.toLowerSlugCase(input: string | string[]): string
StringTools.fromSpaced.toLowerSlugCase(input: string | string[]): string
StringTools.fromCamelCase.toLowerSlugCase(input: string | string[]): string

Convert a string to lower slug case (e.g. this-is-lower-slug-case)

# Parameter Name Required Type Description
0 input Yes string | string[] String or array of strings to convert
Return Type
string Lower slug case string

[↑ Back to StringTools ↑]

toUpperSlugCase

StringTools.toUpperSlugCase(input: string | string[]): string
StringTools.fromSlugCase.toUpperSlugCase(input: string | string[]): string
StringTools.fromSnakeCase.toUpperSlugCase(input: string | string[]): string
StringTools.fromSpaced.toUpperSlugCase(input: string | string[]): string
StringTools.fromCamelCase.toUpperSlugCase(input: string | string[]): string

Convert a string to upper camel case (e.g. THIS-IS-UPPER-SLUG-CASE)

# Parameter Name Required Type Description
0 input Yes string | string[] String or array of strings to convert
Return Type
string Upper slug case string

[↑ Back to StringTools ↑]

toSnakeCase

StringTools.toSnakeCase(input: string | string[], toUpper: boolean): string
StringTools.fromSlugCase.toSnakeCase(input: string | string[], toUpper: boolean): string
StringTools.fromSnakeCase.toSnakeCase(input: string | string[], toUpper: boolean): string
StringTools.fromSpaced.toSnakeCase(input: string | string[], toUpper: boolean): string
StringTools.fromCamelCase.toSnakeCase(input: string | string[], toUpper: boolean): string

Convert a string to snake case (e.g. this_is_snake_case)

# Parameter Name Required Type Default Description
0 input Yes string | string[] String or array of strings to convert
1 toUpper No boolean false Whether to convert the words to upper case
Return Type
string Snake case string

[↑ Back to StringTools ↑]

toLowerSnakeCase

StringTools.toLowerSnakeCase(input: string | string[]): string
StringTools.fromSlugCase.toLowerSnakeCase(input: string | string[]): string
StringTools.fromSnakeCase.toLowerSnakeCase(input: string | string[]): string
StringTools.fromSpaced.toLowerSnakeCase(input: string | string[]): string
StringTools.fromCamelCase.toLowerSnakeCase(input: string | string[]): string

Convert a string to lower snake case (e.g. this_is_lower_snake_case)

# Parameter Name Required Type Description
0 input Yes string | string[] String or array of strings to convert
Return Type
string Lower snake case string

[↑ Back to StringTools ↑]

toUpperSnakeCase

StringTools.toUpperSnakeCase(input: string | string[]): string
StringTools.fromSlugCase.toUpperSnakeCase(input: string | string[]): string
StringTools.fromSnakeCase.toUpperSnakeCase(input: string | string[]): string
StringTools.fromSpaced.toUpperSnakeCase(input: string | string[]): string
StringTools.fromCamelCase.toUpperSnakeCase(input: string | string[]): string

Convert a string to upper snake case (e.g. THIS_IS_UPPER_SNAKE_CASE)

# Parameter Name Required Type Description
0 input Yes string | string[] String or array of strings to convert
Return Type
string Upper snake case string

[↑ Back to StringTools ↑]

toSpaced

StringTools.toSpaced(input: string | string[], toUpper: boolean): string
StringTools.fromSlugCase.toSpaced(input: string | string[], toUpper: boolean): string
StringTools.fromSnakeCase.toSpaced(input: string | string[], toUpper: boolean): string
StringTools.fromSpaced.toSpaced(input: string | string[], toUpper: boolean): string
StringTools.fromCamelCase.toSpaced(input: string | string[], toUpper: boolean): string

Convert a string to spaced case (e.g. this is spaced case)

# Parameter Name Required Type Default Description
0 input Yes string | string[] String or array of strings to convert
1 toUpper No boolean false Whether to convert the words to upper case
Return Type
string Spaced case string

[↑ Back to StringTools ↑]

toLowerSpaced

StringTools.toLowerSpaced(input: string | string[]): string
StringTools.fromSlugCase.toLowerSpaced(input: string | string[]): string
StringTools.fromSnakeCase.toLowerSpaced(input: string | string[]): string
StringTools.fromSpaced.toLowerSpaced(input: string | string[]): string
StringTools.fromCamelCase.toLowerSpaced(input: string | string[]): string

Convert a string to lower spaced case (e.g. this is lower spaced case)

# Parameter Name Required Type Description
0 input Yes string | string[] String or array of strings to convert
Return Type
string Lower spaced case string

[↑ Back to StringTools ↑]

toUpperSpaced

StringTools.toUpperSpaced(input: string | string[]): string
StringTools.fromSlugCase.toUpperSpaced(input: string | string[]): string
StringTools.fromSnakeCase.toUpperSpaced(input: string | string[]): string
StringTools.fromSpaced.toUpperSpaced(input: string | string[]): string
StringTools.fromCamelCase.toUpperSpaced(input: string | string[]): string

Convert a string to upper spaced case (e.g. THIS IS UPPER SPACED CASE)

# Parameter Name Required Type Description
0 input Yes string | string[] String or array of strings to convert
Return Type
string Upper spaced case string

[↑ Back to StringTools ↑]

toCapitalisedSpaced

StringTools.toCapitalisedSpaced(input: string | string[]): string
StringTools.fromSlugCase.toCapitalisedSpaced(input: string | string[]): string
StringTools.fromSnakeCase.toCapitalisedSpaced(input: string | string[]): string
StringTools.fromSpaced.toCapitalisedSpaced(input: string | string[]): string
StringTools.fromCamelCase.toCapitalisedSpaced(input: string | string[]): string

Convert a string to capitalised spaced case (e.g. This Is Capitalised Spaced Case)

# Parameter Name Required Type Description
0 input Yes string | string[] String or array of strings to convert
Return Type
string Capitalised spaced case string

[↑ Back to StringTools ↑]

fromSlugCase

StringTools.fromSlugCase.toLowerCamelCase;
StringTools.fromSlugCase.toUpperCamelCase;
StringTools.fromSlugCase.toCamelCase;
StringTools.fromSlugCase.toLowerSlugCase;
StringTools.fromSlugCase.toUpperSlugCase;
StringTools.fromSlugCase.toSlugCase;
StringTools.fromSlugCase.toLowerSnakeCase;
StringTools.fromSlugCase.toUpperSnakeCase;
StringTools.fromSlugCase.toSnakeCase;
StringTools.fromSlugCase.toLowerSpaced;
StringTools.fromSlugCase.toUpperSpaced;
StringTools.fromSlugCase.toCapitalisedSpaced;
StringTools.fromSlugCase.toSpaced;
StringTools.fromSlugCase.toCharacterSeparated;

Has the following methods:

[↑ Back to StringTools ↑]

fromSnakeCase

StringTools.fromSnakeCase.toLowerCamelCase;
StringTools.fromSnakeCase.toUpperCamelCase;
StringTools.fromSnakeCase.toCamelCase;
StringTools.fromSnakeCase.toLowerSlugCase;
StringTools.fromSnakeCase.toUpperSlugCase;
StringTools.fromSnakeCase.toSlugCase;
StringTools.fromSnakeCase.toLowerSnakeCase;
StringTools.fromSnakeCase.toUpperSnakeCase;
StringTools.fromSnakeCase.toSnakeCase;
StringTools.fromSnakeCase.toLowerSpaced;
StringTools.fromSnakeCase.toUpperSpaced;
StringTools.fromSnakeCase.toCapitalisedSpaced;
StringTools.fromSnakeCase.toSpaced;
StringTools.fromSnakeCase.toCharacterSeparated;

Has the following methods:

[↑ Back to StringTools ↑]

fromSpaced

StringTools.fromSpaced.toLowerCamelCase;
StringTools.fromSpaced.toUpperCamelCase;
StringTools.fromSpaced.toCamelCase;
StringTools.fromSpaced.toLowerSlugCase;
StringTools.fromSpaced.toUpperSlugCase;
StringTools.fromSpaced.toSlugCase;
StringTools.fromSpaced.toLowerSnakeCase;
StringTools.fromSpaced.toUpperSnakeCase;
StringTools.fromSpaced.toSnakeCase;
StringTools.fromSpaced.toLowerSpaced;
StringTools.fromSpaced.toUpperSpaced;
StringTools.fromSpaced.toCapitalisedSpaced;
StringTools.fromSpaced.toSpaced;
StringTools.fromSpaced.toCharacterSeparated;

Has the following methods:

[↑ Back to StringTools ↑]

fromCamelCase

StringTools.fromCamelCase.toLowerCamelCase;
StringTools.fromCamelCase.toUpperCamelCase;
StringTools.fromCamelCase.toCamelCase;
StringTools.fromCamelCase.toLowerSlugCase;
StringTools.fromCamelCase.toUpperSlugCase;
StringTools.fromCamelCase.toSlugCase;
StringTools.fromCamelCase.toLowerSnakeCase;
StringTools.fromCamelCase.toUpperSnakeCase;
StringTools.fromCamelCase.toSnakeCase;
StringTools.fromCamelCase.toLowerSpaced;
StringTools.fromCamelCase.toUpperSpaced;
StringTools.fromCamelCase.toCapitalisedSpaced;
StringTools.fromCamelCase.toSpaced;
StringTools.fromCamelCase.toCharacterSeparated;

Has the following methods:

[↑ Back to StringTools ↑]

matchBrackets

Tools for matching corresponding brackets in a string

[↑ Back to StringTools ↑]

unique

StringTools.matchBrackets.unique(input: string, replaceSymbols: Partial<BracketReplaceSymbols>): string

Replace brackets with symbols and with a unique ID for each bracket pair of each type

const example = '{name: "Jane", info: { age: 31, interests: ["Tennis", "Board Games"] }}';
const uniqued = matchBrackets.unique(example);
uniqued; // '❴0✧name: "Jane", info: ❴1✧ age: 31, interests: ❲0✧"Tennis", "Board Games"❳0✧ ❵1✧❵0✧'
# Parameter Name Required Type Default Description
0 input Yes string String to match brackets in
1 replaceSymbols No Partial<BracketReplaceSymbols> {} Symbols to replace the brackets with
Return Type
string String with the brackets replaced with special symbols

[↑ Back to StringTools ↑]

depth

StringTools.matchBrackets.depth(input: string, replaceSymbols: Partial<BracketReplaceSymbols>): string

Replace brackets with symbols and with a numbers for how deep each bracket pair is for that bracket type

const example = '{name: "Jane", info: { age: 31, interests: ["Tennis", "Board Games"] }}';
const depthed = matchBrackets.depth(example);
depthed; // '❴0✧name: "Jane", info: ❴1✧ age: 31, interests: ❲0✧"Tennis", "Board Games"❳0✧ ❵1✧❵0✧'
# Parameter Name Required Type Default Description
0 input Yes string String to match brackets in
1 replaceSymbols No Partial<BracketReplaceSymbols> {} Symbols to replace the brackets with
Return Type
string String with the brackets replaced with special symbols

[↑ Back to StringTools ↑]

clean

StringTools.matchBrackets.clean(input: string, replaceSymbols: Partial<BracketReplaceSymbols>): string

Return a string that's been matched with unique or depth and replace the symbols with the original brackets. Also works with substrings of such strings.

const example = '{name: "Jane", info: { age: 31, interests: ["Tennis", "Board Games"] }}';
const uniqued = matchBrackets.unique(example);
uniqued; // '❴0✧name: "Jane", info: ❴1✧ age: 31, interests: ❲0✧"Tennis", "Board Games"❳0✧ ❵1✧❵0✧'

const cleaned = matchBrackets.clean(uniqued);
cleaned; // '{name: "Jane", info: { age: 31, interests: ["Tennis", "Board Games"] }}'
# Parameter Name Required Type Default Description
0 input Yes string String to clean
1 replaceSymbols No Partial<BracketReplaceSymbols> {} Symbols to replace the brackets with
Return Type
string String cleaned of the special symbols

[↑ Back to StringTools ↑]

grabDepth

StringTools.matchBrackets.grabDepth(input: string, bracketType: '()' | '[]' | '{}' | '<>' | 'round' | 'square' | 'curly' | 'angle', depthID: number, replaceSymbols: Partial<BracketReplaceSymbols>): string[]

Obtain all the bracketed substrings of the given bracket type from a string at a given depth.

const example = `[
  [
    [1, 2, 3],
    [4, 5, 6]
  ],
  [
    [7, 8, 9]
  ]
]`;
const grabbed = matchBrackets.grabDepth(example, 'square', 2);
grabbed; // [ '[1, 2, 3]', '[4, 5, 6]', '[7, 8, 9]' ]
# Parameter Name Required Type Default Description
0 input Yes string String to match brackets in
1 bracketType No '()' | '[]' | '{}' | '<>' | 'round' | 'square' | 'curly' | 'angle' 'round' Bracket type to match
2 depthID No number 0 Depth ID to match
3 replaceSymbols No Partial<BracketReplaceSymbols> {} Symbols to replace the brackets with
Return Type
string[] Array of bracketed substrings

[↑ Back to StringTools ↑]

grabUnique

StringTools.matchBrackets.grabUnique(input: string, bracketType: '()' | '[]' | '{}' | '<>' | 'round' | 'square' | 'curly' | 'angle', uniqueID: number, replaceSymbols: Partial<BracketReplaceSymbols>): string

Obtain all the bracketed substring of the given bracket type from a string with the given unique ID. e.g. if uniqueID is 3, it will return the bracketed substring for the 4th instance of the opening bracket (see StringTools.matchBrackets.unique)

const example = `[
  [
    [1, 2, 3],
    [4, 5, 6]
  ],
  [
    [7, 8, 9]
  ]
]`;
const grabbed = matchBrackets.grabUnique(example, 'square', 3);
grabbed; // '[4, 5, 6]'
# Parameter Name Required Type Default Description
0 input Yes string String to match brackets in
1 bracketType No '()' | '[]' | '{}' | '<>' | 'round' | 'square' | 'curly' | 'angle' 'round' Bracket type to match
2 uniqueID No number 0 Unique ID to match
3 replaceSymbols No Partial<BracketReplaceSymbols> {} Symbols to replace the brackets with
Return Type
string Bracketed substring

[↑ Back to StringTools ↑]

grab

StringTools.matchBrackets.grab(input: string, bracketType: '()' | '[]' | '{}' | '<>' | 'round' | 'square' | 'curly' | 'angle', replaceSymbols: Partial<BracketReplaceSymbols>): string[]

Grab all the bracketed substrings from a string of the given bracket type.

const example = `[[[1, 2, 3], [4, 5, 6]], [[7, 8, 9]]]`;
matchBrackets.grab(example, 'square');
// [
//   '[[[1, 2, 3], [4, 5, 6]], [[7, 8, 9]]]',
//   '[[1, 2, 3], [4, 5, 6]]',
//   '[1, 2, 3]',
//   '[4, 5, 6]',
//   '[[7, 8, 9]]',
//   '[7, 8, 9]'
// ]
# Parameter Name Required Type Default Description
0 input Yes string String to match brackets in
1 bracketType No '()' | '[]' | '{}' | '<>' | 'round' | 'square' | 'curly' | 'angle' 'round' Bracket type to match
2 replaceSymbols No Partial<BracketReplaceSymbols> {} Symbols to replace the brackets with
Return Type
string[] Array of bracketed substrings

[↑ Back to StringTools ↑]

getReplaceSymbols

StringTools.matchBrackets.getReplaceSymbols(replaceSymbols: Partial<BracketReplaceSymbols>): BracketReplaceSymbols

Get a full set of replace symbols

matchBrackets.getReplaceSymbols();
// {
//   END: '✧',
//   '(': '❪',
//   ')': '❫',
//   '[': '❲',
//   ']': '❳',
//   '{': '❴',
//   '}': '❵',
//   '<': '❰',
//   '>': '❱'
// }

matchBrackets.getReplaceSymbols({
  END: '▣',
  '{': 'START_CURLY',
  '}': 'END_CURLY'
})
// {
//   END: '▣',
//   '(': '❪',
//   ')': '❫',
//   '[': '❲',
//   ']': '❳',
//   '{': 'START_CURLY',
//   '}': 'END_CURLY',
//   '<': '❰',
//   '>': '❱'
// }
# Parameter Name Required Type Default Description
0 replaceSymbols No Partial<BracketReplaceSymbols> {} Partial set of replace symbols to use
Return Type
BracketReplaceSymbols Full set of replace symbols

[↑ Back to StringTools ↑]

BracketReplaceSymbols

StringTools.matchBrackets.BracketReplaceSymbols;

Type for controlling the symbols used to replace brackets

{
  END: string;
  '(': string;
  ')': string;
  '[': string;
  ']': string;
  '{': string;
  '}': string;
  '<': string;
  '>': string;
}

[↑ Back to StringTools ↑]

MathsTools

A collection of mathematical functions.

Note: The field is 'Mathematics', and so it is 'MathsTools' not 'MathTools'

[↑ Back to top ↑]

fixFloat

ff(num: number, precision: number): number
MathsTools.ff(num: number, precision: number): number
MathsTools.fixFloat(num: number, precision: number): number

Fixes floating point errors that may occur when adding/subtracting/multiplying/dividing real/float numbers

Can also be used to round numbers to a given precision

Note: 'fixFloat' is not a great name, but it's what I've always called it, so I'm sticking with it. 'ff' is a shorthand alias.

0.1 + 0.2 // 0.30000000000000004
MathsTools.fixFloat(0.1 + 0.2) // 0.3
# Parameter Name Required Type Default Description
0 num Yes number Number to fix
1 precision No number 6 Precision to round to
Return Type
number Unbroken number

[↑ Back to MathsTools ↑]

addAll

MathsTools.addAll(...nums: number[]): number

Adds all numbers together. Each argument is a number (use spread operator to pass in an array) similar to Math.min/Math.max

MathsTools.addAll(1, 2, 3, 4, 5); // 15
# Parameter Name Required Type Description
0… nums No number[] Numbers to add
Return Type
number Sum of all numbers

[↑ Back to MathsTools ↑]

round

floorTo

MathsTools.floorTo(to: number, value: number): number
MathsTools.round.floorTo(to: number, value: number): number

Floors a number down to the nearest multiple of the given number.

MathsTools.round.floorTo(10, 102); // 100
MathsTools.round.floorTo(5, 53); // 50
MathsTools.round.floorTo(0.1, 0.25); // 0.2
# Parameter Name Required Type Description
0 to Yes number Target to floor to
1 value Yes number Number to floor
Return Type
number Floored number

[↑ Back to MathsTools ↑]

roundTo

MathsTools.round.to(to: number, value: number): number
MathsTools.roundTo(to: number, value: number): number
MathsTools.round.roundTo(to: number, value: number): number

Floors a number down to the nearest multiple of the given number.

MathsTools.round.to(10, 102); // 100
MathsTools.round.to(5, 53); // 55
MathsTools.round.to(0.1, 0.25); // 0.3
# Parameter Name Required Type Description
0 to Yes number Target to round to
1 value Yes number Number to round
Return Type
number Rounded number

[↑ Back to MathsTools ↑]

ceilTo

MathsTools.ceilTo(to: number, value: number): number
MathsTools.round.ceilTo(to: number, value: number): number

Floors a number down to the nearest multiple of the given number.

MathsTools.round.ceilTo(10, 102); // 110
MathsTools.round.ceilTo(5, 53); // 55
MathsTools.round.ceilTo(0.1, 0.25); // 0.3
# Parameter Name Required Type Description
0 to Yes number Target to ceil to
1 value Yes number Number to ceil
Return Type
number Ceiled number

[↑ Back to MathsTools ↑]

lerp

MathsTools.lerp(progress: number, fromVal: number, toVal: number): number

Linearly interpolates between two values.

MathsTools.lerp(0.5, 0, 10); // 5
# Parameter Name Required Type Description
0 progress Yes number Progress to interpolate (0-1)
1 fromVal Yes number Start value (what the progress is at 0)
2 toVal Yes number End value (what the progress is at 1)
Return Type
number Interpolated number

[↑ Back to MathsTools ↑]

lerpArray

MathsTools.lerpArray(progress: number, fromArr: number[], toArr: number[]): number[]

Linearly interpolates between the values of 2 arrays.

MathsTools.lerpArray(0.5, [0, 0, 0], [10, 100, 1000]) // [5, 50, 500]
# Parameter Name Required Type Description
0 progress Yes number Progress to interpolate (0-1)
1 fromArr Yes number[] Start values (what the progress is at 0)
2 toArr Yes number[] End values (what the progress is at 1)
Return Type
number[] Interpolated array

[↑ Back to MathsTools ↑]

lerpObj

MathsTools.lerpObj(progress: number, fromObj: T, toObj: T): T

Linearly interpolates between the values of 2 arrays.

MathsTools.lerpObj(0.5, {'ARS': 0, 'CHE': 0, 'FUL': 0}, {'ARS': 100, 'CHE': 10, 'FUL': 20}) // {'ARS': 50, 'CHE': 5, 'FUL': 10}
# Parameter Name Required Type Description
0 progress Yes number Progress to interpolate (0-1)
1 fromObj Yes T Start values (what the progress is at 0)
2 toObj Yes T End values (what the progress is at 1)
Return Type
T Interpolated object

[↑ Back to MathsTools ↑]

clamp

MathsTools.clamp(value: number, min: number, max: number): number

Clamps a value between a min and max.

MathsTools.clamp(5, 0, 10); // 5
MathsTools.clamp(-5, 0, 10); // 0
# Parameter Name Required Type Description
0 value Yes number Value to clamp
1 min Yes number Minimum value
2 max Yes number Maximum value
Return Type
number Clamped number

[↑ Back to MathsTools ↑]

getOrdinal

MathsTools.getOrdinal(num: number): "th" | "st" | "nd" | "rd"

Gets the ordinal suffix for a number.

Note: all numbers are treated as positive. Note: all decimals are 'th' (e.g. 1.2 is '1.2th') as they are tenth, hundredth, thousandth, etc.

MathsTools.getOrdinal(1); // 'st'
MathsTools.getOrdinal(2); // 'nd'
MathsTools.getOrdinal(3); // 'rd'
MathsTools.getOrdinal(4); // 'th'

MathsTools.getOrdinal(11); // 'th'
MathsTools.getOrdinal(12); // 'th'
MathsTools.getOrdinal(13); // 'th'
MathsTools.getOrdinal(14); // 'th'

MathsTools.getOrdinal(21); // 'st'
MathsTools.getOrdinal(22); // 'nd'
MathsTools.getOrdinal(23); // 'rd'
MathsTools.getOrdinal(24); // 'th'
# Parameter Name Required Type Default Description
0 num No number 0 Number to get the ordinal for
Return Type
"th" | "st" | "nd" | "rd" Ordinal suffix

[↑ Back to MathsTools ↑]

PromiseTools

A collection of promise utilities

[↑ Back to top ↑]

getDeferred

getDeferred(): DeferredPromise<T>
PromiseTools.getDeferred(): DeferredPromise<T>

A deferred promise

import { getDeferred } from 'swiss-ak';

const run = () => {
  const deferred = getDeferred<number>();

  doSomethingWithACallback('a', 'b', (err: Error, result: number) => {
    // callback (just an example - don't actually do this this way)
    if (err) return deferred.reject(err);
    deferred.resolve(result);
  });

  return deferred.promise;
};

const luckyNumber: number = await run();
Return Type
DeferredPromise<T> Deferred promise

[↑ Back to PromiseTools ↑]

all

all(items: PromiseTools.PromiseItem<T>[]): Promise<T[]>
PromiseTools.all(items: PromiseTools.PromiseItem<T>[]): Promise<T[]>

Similar to Promise.all, but accepts values, functions, and promises.

# Parameter Name Required Type Description
0 items Yes PromiseTools.PromiseItem<T>[] Items to wait for
Return Type
Promise<T[]> Promise that resolves to an array of the results

[↑ Back to PromiseTools ↑]

allLimit

allLimit(limit: number, items: PromiseTools.PromiseItem<T>[], noThrow: boolean): Promise<T[]>
PromiseTools.allLimit(limit: number, items: PromiseTools.PromiseItem<T>[], noThrow: boolean): Promise<T[]>

Like Promise.all, but limits the numbers of concurrently running items.

Takes an array of functions (that return Promises), rather than an array of Promises

import { PromiseTools, timer, ms, seconds } from 'swiss-ak';

const give = async (delay: ms, result: number, label: string) => {
  await waitFor(delay);
  timer.end(label);
  return result;
};

timer.start('allLimit', 'a', 'b', 'c', 'd');

const results = PromiseTools.allLimit<number>(2, [
  give(seconds(5), 1, 'a'),
  give(seconds(5), 2, 'b'),
  give(seconds(5), 3, 'c'),
  give(seconds(5), 4, 'd')
]);

timer.end('allLimit');

console.log(results); // [ 1, 2, 3, 4 ]

timer.log();
// Times:
// 	allLimit: 10s
// 	a: 5s
// 	b: 5s
// 	c: 10s
// 	d: 10s
# Parameter Name Required Type Default Description
0 limit Yes number Maximum number of items to run concurrently
1 items Yes PromiseTools.PromiseItem<T>[] Items to wait for
2 noThrow No boolean false Whether to prevent throwing errors
Return Type
Promise<T[]> Promise that resolves to an array of the results

[↑ Back to PromiseTools ↑]

each

each(items: T[], func: (item: T, index: number, array: T[]) => Promise<any>): Promise<void>
PromiseTools.each(items: T[], func: (item: T, index: number, array: T[]) => Promise<any>): Promise<void>

Run an async function against each item in an array

import { PromiseTools, ms, seconds, wait } from 'swiss-ak';

const arr = [1, 2, 3, 4];

await PromiseTools.each<number>(arr, async (val: number) => {
  await wait(seconds(2));
  sendToSomewhere(val);
});
console.log(''); // after 2 seconds
# Parameter Name Required Type Description
0 items Yes T[] Items to iterate over
1 func Yes (item: T, index: number, array: T[]) => Promise<any> Function to apply to each item
Return Type
Promise<void> Promise that resolves when all items have been processed

[↑ Back to PromiseTools ↑]

eachLimit

eachLimit(limit: number, items: T[], func: (item: T, index: number, array: T[]) => Promise<any>): Promise<void>
PromiseTools.eachLimit(limit: number, items: T[], func: (item: T, index: number, array: T[]) => Promise<any>): Promise<void>

Run an async function against each item in an array, limiting the number of items that can run concurrently.

See PromiseTools.allLimit for information about limited functions.

import { PromiseTools, ms, seconds, wait } from 'swiss-ak';

const arr = [1, 2, 3, 4];

await PromiseTools.eachLimit<number>(2, arr, async (val: number) => {
  await wait(seconds(2));
  sendToSomewhere(val);
});
console.log(''); // after 4 seconds
# Parameter Name Required Type Description
0 limit Yes number Maximum number of items to run concurrently
1 items Yes T[] Items to iterate over
2 func Yes (item: T, index: number, array: T[]) => Promise<any> Function to apply to each item
Return Type
Promise<void> Promise that resolves when all items have been processed

[↑ Back to PromiseTools ↑]

map

map(items: T[], func: (item: T, index: number, array: T[]) => Promise<U>): Promise<U[]>
PromiseTools.map(items: T[], func: (item: T, index: number, array: T[]) => Promise<U>): Promise<U[]>

Run an async map function against each item in an array, mapping the results to a returned array

import { PromiseTools, ms, seconds, wait } from 'swiss-ak';

const arr = [1, 2, 3, 4];

const mapped = await PromiseTools.map<number>(arr, async (val: number) => {
  await wait(seconds(2));
  return val * 2;
});

console.log(mapped); // [2, 4, 6, 8] (after 2 seconds)
# Parameter Name Required Type Description
0 items Yes T[] Items to iterate over
1 func Yes (item: T, index: number, array: T[]) => Promise<U> Map function to apply to each item
Return Type
Promise<U[]> Promise that resolves to a mapped array of the results

[↑ Back to PromiseTools ↑]

mapLimit

mapLimit(limit: number, items: T[], func: (item: T, index: number, array: T[]) => Promise<U>): Promise<U[]>
PromiseTools.mapLimit(limit: number, items: T[], func: (item: T, index: number, array: T[]) => Promise<U>): Promise<U[]>

Run an async map function against each item in an array, mapping the results to a returned array, and limiting the number of items that can run concurrently.

See PromiseTools.allLimit for information about limited functions.

import { PromiseTools, ms, seconds, wait } from 'swiss-ak';

const arr = [1, 2, 3, 4];

const mapped = await PromiseTools.mapLimit<number>(2, arr, async (val: number) => {
  await wait(seconds(2));
  return val * 2;
});

console.log(mapped); // [2, 4, 6, 8] (after 4 seconds)
# Parameter Name Required Type Description
0 limit Yes number Maximum number of items to run concurrently
1 items Yes T[] Items to iterate over
2 func Yes (item: T, index: number, array: T[]) => Promise<U> Map function to apply to each item
Return Type
Promise<U[]> Promise that resolves to a mapped array of the results

[↑ Back to PromiseTools ↑]

allObj

allObj(input: T): Promise<AwaitedObject<T>>
PromiseTools.allObj(input: T): Promise<AwaitedObject<T>>

Like Promise.all, but pass/receive objects rather than arrays

import { PromiseTools, timer, ms, seconds } from 'swiss-ak';

const give = async (delay: ms, result: number, label: string) => {
  await waitFor(delay);
  timer.end(label);
  return result;
};

timer.start('allObj', 'a', 'b', 'c');

const results = PromiseTools.allObj<number>({
  a: give(seconds(10), 1, 'a'),
  b: give(seconds(15), 2, 'b'),
  c: give(seconds(20), 3, 'c')
});

timer.end('allObj');

console.log(results); // { a: 1, b: 2, c: 3 }

timer.log();
// Times:
// 	allObj: 20s
// 	a: 10s
// 	b: 15s
// 	c: 20s
# Parameter Name Required Type Description
0 input Yes T Object with properties to wait for
Return Type
Promise<AwaitedObject<T>> Promise that resolves to an object with the results

[↑ Back to PromiseTools ↑]

allLimitObj

allLimitObj(limit: number, input: T, noThrow: boolean): Promise<AwaitedObject<T>>
PromiseTools.allLimitObj(limit: number, input: T, noThrow: boolean): Promise<AwaitedObject<T>>

A mix of allObj and allLimit.

Takes an array of functions (that return Promises), and limits the numbers of concurrently running items.

import { PromiseTools, timer, ms, seconds } from 'swiss-ak';

const give = async (delay: ms, result: number, label: string) => {
  await waitFor(delay);
  timer.end(label);
  return result;
};

timer.start('allLimitObj', 'a', 'b', 'c', 'd');

const results = PromiseTools.allLimitObj<number>(2, {
  a: give(seconds(5), 1, 'a'),
  b: give(seconds(5), 2, 'b'),
  c: give(seconds(5), 3, 'c'),
  d: give(seconds(5), 4, 'd')
});

timer.end('allLimitObj');

console.log(results); // { a: 1, b: 2, c: 3, d: 4 }

timer.log();
// Times:
// 	allLimitObj: 10s
// 	a: 5s
// 	b: 5s
// 	c: 10s
// 	d: 10s
# Parameter Name Required Type Default Description
0 limit Yes number Maximum number of items to run concurrently
1 input Yes T Object with properties to wait for
2 noThrow No boolean false Whether to prevent throwing errors
Return Type
Promise<AwaitedObject<T>> Promise that resolves to an object with the results

[↑ Back to PromiseTools ↑]

PromiseFunc

PromiseFunc<T>;

A function that returns a promise

[↑ Back to PromiseTools ↑]

PromiseItem

PromiseItem<T>;

A promise, a function that returns a promise (see PromiseFunc), or a value

Accepted by PromiseTools.all, PromiseTools.allLimit, PromiseTools.allObj, and PromiseTools.allLimitObj in place of promises

[↑ Back to PromiseTools ↑]

DeferredPromise

DeferredPromise;
PromiseTools.DeferredPromise;

A deferred promise

[↑ Back to PromiseTools ↑]

ColourTools

A collection of functions for working with colours.

[↑ Back to top ↑]

ColourValues

ColourTools.ColourValues;

A type with 3 numbers:

  • red [0-255]
  • green [0-255]
  • blue [0-255]

[↑ Back to ColourTools ↑]

HSLValues

ColourTools.HSLValues;

A type with 3 numbers:

  • hue [0-360]
  • saturation [0-100]
  • lightness [0-100]

[↑ Back to ColourTools ↑]

namedColours

ColourTools.namedColours;

A dictionary of different colour names and their RGB values

Name RGB Hex
aliceblue 240, 248, 255 #f0f8ff
antiquewhite 250, 235, 215 #faebd7
aqua 0, 255, 255 #00ffff
aquamarine 127, 255, 212 #7fffd4
azure 240, 255, 255 #f0ffff
beige 245, 245, 220 #f5f5dc
bisque 255, 228, 196 #ffe4c4
black 0, 0, 0 #000000
blanchedalmond 255, 235, 205 #ffebcd
blue 0, 0, 255 #0000ff
blueviolet 138, 43, 226 #8a2be2
brown 165, 42, 42 #a52a2a
burlywood 222, 184, 135 #deb887
cadetblue 95, 158, 160 #5f9ea0
chartreuse 127, 255, 0 #7fff00
chocolate 210, 105, 30 #d2691e
coral 255, 127, 80 #ff7f50
cornflowerblue 100, 149, 237 #6495ed
cornsilk 255, 248, 220 #fff8dc
crimson 220, 20, 60 #dc143c
cyan 0, 255, 255 #00ffff
darkblue 0, 0, 139 #00008b
darkcyan 0, 139, 139 #008b8b
darkgoldenrod 184, 134, 11 #b8860b
darkgray 169, 169, 169 #a9a9a9
darkgreen 0, 100, 0 #006400
darkgrey 169, 169, 169 #a9a9a9
darkkhaki 189, 183, 107 #bdb76b
darkmagenta 139, 0, 139 #8b008b
darkolivegreen 85, 107, 47 #556b2f
darkorange 255, 140, 0 #ff8c00
darkorchid 153, 50, 204 #9932cc
darkred 139, 0, 0 #8b0000
darksalmon 233, 150, 122 #e9967a
darkseagreen 143, 188, 143 #8fbc8f
darkslateblue 72, 61, 139 #483d8b
darkslategray 47, 79, 79 #2f4f4f
darkslategrey 47, 79, 79 #2f4f4f
darkturquoise 0, 206, 209 #00ced1
darkviolet 148, 0, 211 #9400d3
deeppink 255, 20, 147 #ff1493
deepskyblue 0, 191, 255 #00bfff
dimgray 105, 105, 105 #696969
dimgrey 105, 105, 105 #696969
dodgerblue 30, 144, 255 #1e90ff
firebrick 178, 34, 34 #b22222
floralwhite 255, 250, 240 #fffaf0
forestgreen 34, 139, 34 #228b22
fractal 128, 128, 128 #808080
fuchsia 255, 0, 255 #ff00ff
gainsboro 220, 220, 220 #dcdcdc
ghostwhite 248, 248, 255 #f8f8ff
gold 255, 215, 0 #ffd700
goldenrod 218, 165, 32 #daa520
gray0 0, 0, 0 #000000
gray1 3, 3, 3 #030303
gray2 5, 5, 5 #050505
gray3 8, 8, 8 #080808
gray4 10, 10, 10 #0a0a0a
gray5 13, 13, 13 #0d0d0d
gray6 15, 15, 15 #0f0f0f
gray7 18, 18, 18 #121212
gray8 20, 20, 20 #141414
gray9 23, 23, 23 #171717
gray10 26, 26, 26 #1a1a1a
gray11 28, 28, 28 #1c1c1c
gray12 31, 31, 31 #1f1f1f
gray13 33, 33, 33 #212121
gray14 36, 36, 36 #242424
gray15 38, 38, 38 #262626
gray16 41, 41, 41 #292929
gray17 43, 43, 43 #2b2b2b
gray18 46, 46, 46 #2e2e2e
gray19 48, 48, 48 #303030
gray20 51, 51, 51 #333333
gray21 54, 54, 54 #363636
gray22 56, 56, 56 #383838
gray23 59, 59, 59 #3b3b3b
gray24 61, 61, 61 #3d3d3d
gray25 64, 64, 64 #404040
gray26 66, 66, 66 #424242
gray27 69, 69, 69 #454545
gray28 71, 71, 71 #474747
gray29 74, 74, 74 #4a4a4a
gray30 77, 77, 77 #4d4d4d
gray31 79, 79, 79 #4f4f4f
gray32 82, 82, 82 #525252
gray33 84, 84, 84 #545454
gray34 87, 87, 87 #575757
gray35 89, 89, 89 #595959
gray36 92, 92, 92 #5c5c5c
gray37 94, 94, 94 #5e5e5e
gray38 97, 97, 97 #616161
gray39 99, 99, 99 #636363
gray40 102, 102, 102 #666666
gray41 105, 105, 105 #696969
gray42 107, 107, 107 #6b6b6b
gray43 110, 110, 110 #6e6e6e
gray44 112, 112, 112 #707070
gray45 115, 115, 115 #737373
gray46 117, 117, 117 #757575
gray47 120, 120, 120 #787878
gray48 122, 122, 122 #7a7a7a
gray49 125, 125, 125 #7d7d7d
gray50 127, 127, 127 #7f7f7f
gray51 130, 130, 130 #828282
gray52 133, 133, 133 #858585
gray53 135, 135, 135 #878787
gray54 138, 138, 138 #8a8a8a
gray55 140, 140, 140 #8c8c8c
gray56 143, 143, 143 #8f8f8f
gray57 145, 145, 145 #919191
gray58 148, 148, 148 #949494
gray59 150, 150, 150 #969696
gray60 153, 153, 153 #999999
gray61 156, 156, 156 #9c9c9c
gray62 158, 158, 158 #9e9e9e
gray63 161, 161, 161 #a1a1a1
gray64 163, 163, 163 #a3a3a3
gray65 166, 166, 166 #a6a6a6
gray66 168, 168, 168 #a8a8a8
gray67 171, 171, 171 #ababab
gray68 173, 173, 173 #adadad
gray69 176, 176, 176 #b0b0b0
gray70 179, 179, 179 #b3b3b3
gray71 181, 181, 181 #b5b5b5
gray72 184, 184, 184 #b8b8b8
gray73 186, 186, 186 #bababa
gray74 189, 189, 189 #bdbdbd
gray75 191, 191, 191 #bfbfbf
gray76 194, 194, 194 #c2c2c2
gray77 196, 196, 196 #c4c4c4
gray78 199, 199, 199 #c7c7c7
gray79 201, 201, 201 #c9c9c9
gray80 204, 204, 204 #cccccc
gray81 207, 207, 207 #cfcfcf
gray82 209, 209, 209 #d1d1d1
gray83 212, 212, 212 #d4d4d4
gray84 214, 214, 214 #d6d6d6
gray85 217, 217, 217 #d9d9d9
gray86 219, 219, 219 #dbdbdb
gray87 222, 222, 222 #dedede
gray88 224, 224, 224 #e0e0e0
gray89 227, 227, 227 #e3e3e3
gray90 229, 229, 229 #e5e5e5
gray91 232, 232, 232 #e8e8e8
gray92 235, 235, 235 #ebebeb
gray93 237, 237, 237 #ededed
gray94 240, 240, 240 #f0f0f0
gray95 242, 242, 242 #f2f2f2
gray96 245, 245, 245 #f5f5f5
gray97 247, 247, 247 #f7f7f7
gray98 250, 250, 250 #fafafa
gray99 252, 252, 252 #fcfcfc
gray100 255, 255, 255 #ffffff
gray 126, 126, 126 #7e7e7e
green 0, 128, 0 #008000
greenyellow 173, 255, 47 #adff2f
grey 128, 128, 128 #808080
honeydew 240, 255, 240 #f0fff0
hotpink 255, 105, 180 #ff69b4
indianred 205, 92, 92 #cd5c5c
indigo 75, 0, 130 #4b0082
ivory 255, 255, 240 #fffff0
khaki 240, 230, 140 #f0e68c
lavender 230, 230, 250 #e6e6fa
lavenderblush 255, 240, 245 #fff0f5
lawngreen 124, 252, 0 #7cfc00
lemonchiffon 255, 250, 205 #fffacd
lightblue 173, 216, 230 #add8e6
lightcoral 240, 128, 128 #f08080
lightcyan 224, 255, 255 #e0ffff
lightgoldenrodyellow 250, 250, 210 #fafad2
lightgray 211, 211, 211 #d3d3d3
lightgreen 144, 238, 144 #90ee90
lightgrey 211, 211, 211 #d3d3d3
lightpink 255, 182, 193 #ffb6c1
lightsalmon 255, 160, 122 #ffa07a
lightseagreen 32, 178, 170 #20b2aa
lightskyblue 135, 206, 250 #87cefa
lightslategray 119, 136, 153 #778899
lightslategrey 119, 136, 153 #778899
lightsteelblue 176, 196, 222 #b0c4de
lightyellow 255, 255, 224 #ffffe0
lime 0, 255, 0 #00ff00
limegreen 50, 205, 50 #32cd32
linen 250, 240, 230 #faf0e6
magenta 255, 0, 255 #ff00ff
maroon 128, 0, 0 #800000
mediumaquamarine 102, 205, 170 #66cdaa
mediumblue 0, 0, 205 #0000cd
mediumorchid 186, 85, 211 #ba55d3
mediumpurple 147, 112, 219 #9370db
mediumseagreen 60, 179, 113 #3cb371
mediumslateblue 123, 104, 238 #7b68ee
mediumspringgreen 0, 250, 154 #00fa9a
mediumturquoise 72, 209, 204 #48d1cc
mediumvioletred 199, 21, 133 #c71585
midnightblue 25, 25, 112 #191970
mintcream 245, 255, 250 #f5fffa
mistyrose 255, 228, 225 #ffe4e1
moccasin 255, 228, 181 #ffe4b5
navajowhite 255, 222, 173 #ffdead
navy 0, 0, 128 #000080
none 0, 0, 0 #000000
oldlace 253, 245, 230 #fdf5e6
olive 128, 128, 0 #808000
olivedrab 107, 142, 35 #6b8e23
orange 255, 165, 0 #ffa500
orangered 255, 69, 0 #ff4500
orchid 218, 112, 214 #da70d6
palegoldenrod 238, 232, 170 #eee8aa
palegreen 152, 251, 152 #98fb98
paleturquoise 175, 238, 238 #afeeee
palevioletred 219, 112, 147 #db7093
papayawhip 255, 239, 213 #ffefd5
peachpuff 255, 218, 185 #ffdab9
peru 205, 133, 63 #cd853f
pink 255, 192, 203 #ffc0cb
plum 221, 160, 221 #dda0dd
powderblue 176, 224, 230 #b0e0e6
purple 128, 0, 128 #800080
red 255, 0, 0 #ff0000
rosybrown 188, 143, 143 #bc8f8f
royalblue 65, 105, 225 #4169e1
saddlebrown 139, 69, 19 #8b4513
salmon 250, 128, 114 #fa8072
sandybrown 244, 164, 96 #f4a460
seagreen 46, 139, 87 #2e8b57
seashell 255, 245, 238 #fff5ee
sienna 160, 82, 45 #a0522d
silver 192, 192, 192 #c0c0c0
skyblue 135, 206, 235 #87ceeb
slateblue 106, 90, 205 #6a5acd
slategray 112, 128, 144 #708090
slategrey 112, 128, 144 #708090
snow 255, 250, 250 #fffafa
springgreen 0, 255, 127 #00ff7f
steelblue 70, 130, 180 #4682b4
tan 210, 180, 140 #d2b48c
teal 0, 128, 128 #008080
thistle 216, 191, 216 #d8bfd8
tomato 255, 99, 71 #ff6347
turquoise 64, 224, 208 #40e0d0
violet 238, 130, 238 #ee82ee
wheat 245, 222, 179 #f5deb3
white 255, 255, 255 #ffffff
whitesmoke 245, 245, 245 #f5f5f5
yellow 255, 255, 0 #ffff00
yellowgreen 154, 205, 50 #9acd32
ColourTools.namedColours.blue // [0, 0, 255]
ColourTools.namedColours.red // [255, 0, 0]
ColourTools.namedColours.green // [0, 255, 0]

ColourTools.namedColours.azure // [240, 255, 255]
ColourTools.namedColours.darkorange // [255, 140, 0]
ColourTools.namedColours.dodgerblue // [30, 144, 255]

[↑ Back to ColourTools ↑]

parse

ColourTools.parse(input: string): ColourValues

Parse a string into a colour object (RGB array) Not extensive. Currently limited to:

  • 3 char hexes
  • 6 char hexes
  • comma separated RGB values
  • named colours (from namedColours dictionary)
ColourTools.parse('#FF0000') // [255, 0, 0]
ColourTools.parse('rgb(255, 0, 0)') // [255, 0, 0]
ColourTools.parse('red') // [255, 0, 0]
# Parameter Name Required Type Description
0 input Yes string Input string to parse
Return Type
ColourValues RGB array of the parsed colour

[↑ Back to ColourTools ↑]

toHex

ColourTools.toHex(colour: ColourValues): string

Convert a colour object (RGB array) to a hex string

ColourTools.toHex([255, 0, 0]) // '#FF0000'
# Parameter Name Required Type Description
0 colour Yes ColourValues Colour to convert to a hex string
Return Type
string Hex string of the colour

[↑ Back to ColourTools ↑]

getLuminance

ColourTools.getLuminance(rgb: ColourValues): number

IMPORTANT: This is not the same as the HSL lightness value.

Get the luminance value of a given colour.

Between 0 and 255. Calculated using the formula: (RED × 0.299) + (GREEN × 0.587) + (BLUE × 0.114)

Is the Y (Luma) component of the YUV444 color model.

ColourTools.getLuminance([255, 0, 0]); // 76.245
ColourTools.getLuminance([0, 255, 0]); // 149.685
ColourTools.getLuminance([0, 0, 255]); // 29.07
# Parameter Name Required Type Description
0 rgb Yes ColourValues Colour to get the luminance of
Return Type
number Luminance value of the colour

[↑ Back to ColourTools ↑]

toYUV

ColourTools.toYUV(rgb: ColourValues): ColourValues

Convert a colour object (RGB array) to a YUV array.

See https://en.wikipedia.org/wiki/YUV#Y%E2%80%B2UV444_to_RGB888_conversion

ColourTools.toYUV([255, 0, 0]); // [76.245, 112.439, -38.094]
# Parameter Name Required Type Description
0 rgb Yes ColourValues Colour to convert to a YUV array
Return Type
ColourValues YUV array of the colour

[↑ Back to ColourTools ↑]

toHSL

ColourTools.toHSL(colour: ColourValues, round: boolean): HSLValues

Convert a RGB array to a HSL array.

Adapted from https://www.30secondsofcode.org/js/s/rgb-to-hsl

ColourTools.toHSL([255, 0, 0]); // [0, 100, 50]
ColourTools.toHSL([0, 255, 0]); // [120, 100, 50]
# Parameter Name Required Type Default Description
0 colour Yes ColourValues Colour to convert to a HSL array
1 round No boolean true Whether to round the result
Return Type
HSLValues HSL array of the colour

[↑ Back to ColourTools ↑]

fromHSL

ColourTools.fromHSL(hsl: HSLValues, round: boolean): ColourValues

Convert a HSL array to a RGB array.

Adapted from https://www.30secondsofcode.org/js/s/hsl-to-rgb

ColourTools.fromHSL([0, 100, 50]); // [255, 0, 0]
ColourTools.fromHSL([120, 100, 50]); // [0, 255, 0]
# Parameter Name Required Type Default Description
0 hsl Yes HSLValues HSL array to convert to a RGB array
1 round No boolean true Whether to round the result
Return Type
ColourValues RGB array of the colour

[↑ Back to ColourTools ↑]

invertColour

ColourTools.invertColour(rgb: ColourValues): ColourValues

Get the opposite colour of a given colour.

ColourTools.invertColour([255, 0, 0]); // [0, 255, 255]
ColourTools.invertColour([0, 255, 0]); // [ 255, 0, 255 ]
ColourTools.invertColour([0, 0, 255]); // [ 255, 255, 0 ]
# Parameter Name Required Type Description
0 rgb Yes ColourValues Colour to invert
Return Type
ColourValues RGB array of the inverted colour

[↑ Back to ColourTools ↑]

getContrastedColour

ColourTools.getContrastedColour(colour: ColourValues): ColourValues

Get the colour that contrasts the most with a given colour. (White or black)

Returned colour can be used as a text colour on top of the provided colour

ColourTools.getContrastedColour([255, 0, 0]); // [255, 255, 255]
ColourTools.getContrastedColour([255, 255, 0]); // [0, 0, 0]
# Parameter Name Required Type Description
0 colour Yes ColourValues Colour to get the contrasted colour of
Return Type
ColourValues RGB array of the contrasted colour

[↑ Back to ColourTools ↑]

getLimitedColour

ColourTools.getLimitedColour(colour: ColourValues, checkFn: (hsl: HSLValues) => boolean, adjustFn: (hsl: HSLValues) => HSLValues): ColourValues

Adjust a colour if a certain condition is met. Used for lightening/darkening colours that are too light/dark

All values in functions are HSL

ColourTools.getLimitedColour([255, 255, 255], ([h,s,l]) => l > 90, ([h,s,l]) => [h, s, 90]); // [ 230, 230, 230 ]
ColourTools.getLimitedColour([128, 128, 128], ([h,s,l]) => l > 90, ([h,s,l]) => [h, s, 90]); // [ 128, 128, 128 ]
# Parameter Name Required Type Description
0 colour Yes ColourValues Colour to limit
1 checkFn Yes (hsl: HSLValues) => boolean Function to check if the colour should be limited
2 adjustFn Yes (hsl: HSLValues) => HSLValues Function to adjust the colour if it should be limited
Return Type
ColourValues RGB array of the limited colour

[↑ Back to ColourTools ↑]

TimeTools

A collection of time-related utility functions.

[↑ Back to top ↑]

toReadableDuration

TimeTools.toReadableDuration(duration: ms, longNames: boolean, maxUnits: number): string

Converts a duration in milliseconds to a human readable string.

TimeTools.toReadableDuration(20); // '20ms'
TimeTools.toReadableDuration(seconds(59)); // '59s'
TimeTools.toReadableDuration(seconds(60)); // '1m'
TimeTools.toReadableDuration(hours(23)); // '23h'
TimeTools.toReadableDuration(hours(24)); // '1d'
TimeTools.toReadableDuration(days(10)); // '10d'

TimeTools.toReadableDuration(20, true) // '20 milliseconds'
TimeTools.toReadableDuration(seconds(59), true) // '59 seconds'
TimeTools.toReadableDuration(seconds(60), true) // '1 minute'
TimeTools.toReadableDuration(hours(23), true) // '23 hours'
TimeTools.toReadableDuration(hours(24), true) // '1 day'
TimeTools.toReadableDuration(days(10), true) // '10 days'

const realisticDuration = days(10) + hours(2) + seconds(31) + 512; // 871231512
TimeTools.toReadableDuration(realisticDuration, true, 4) // '10 days, 2 hours, 31 seconds & 512 milliseconds'
TimeTools.toReadableDuration(realisticDuration, true) // '10 days, 2 hours & 31 seconds'
TimeTools.toReadableDuration(realisticDuration, true, 2) // '10 days & 2 hours'
# Parameter Name Required Type Default Description
0 duration Yes ms Duration in milliseconds
1 longNames No boolean false Whether to use long names
2 maxUnits No number 3 Maximum number of units to display
Return Type
string Human readable duration

[↑ Back to TimeTools ↑]

ErrorTools

Functions for handling errors.

[↑ Back to top ↑]

tryOr

tryOr(orValue: T, func: (...args: A[]) => Promise<T>, ...args: A[]): Promise<T>
ErrorTools.tryOr(orValue: T, func: (...args: A[]) => Promise<T>, ...args: A[]): Promise<T>

Try to execute a function and return its result if it succeeds, or return the default value if it fails.

const result = ErrorTools.tryOr('default', () => getSomething());
# Parameter Name Required Type Description
0 orValue Yes T Default value to return if the function fails
1 func Yes (...args: A[]) => Promise<T> Function to try
2… args No A[] Arguments to pass to the function
Return Type
Promise<T> Promise that resolves to the result of the function, or the default value if it fails

[↑ Back to ErrorTools ↑]

retry

retry(maxTries: number, delay: ms, suppress: boolean, run: (attemptNumber) => T): Promise<T>
ErrorTools.retry(maxTries: number, delay: ms, suppress: boolean, run: (attemptNumber) => T): Promise<T>

Try to execute a function and return its result if it succeeds, or retry a given number of times until it succeeds.

const result = ErrorTools.retry(5, seconds(1), true, () => getSomething());
# Parameter Name Required Type Default Description
0 maxTries No number 10 Maximum number of tries
1 delay No ms 0 Delay between tries
2 suppress No boolean true Whether to suppress the error
3 run No (attemptNumber) => T fn.result(undefined as T) Function to run on each attempt
Return Type
Promise<T> Promise that resolves to the result of the function, or undefined if it fails after all tries

[↑ Back to ErrorTools ↑]

retryOr

retryOr(orValue: T, maxTries: number, delay: ms, run: () => T | Promise<T>): Promise<T>
ErrorTools.retryOr(orValue: T, maxTries: number, delay: ms, run: () => T | Promise<T>): Promise<T>

Combination of retry and tryOr.

Try to execute a function and return its result if it succeeds, or retry a given number of times until it succeeds. Return the default value if it fails too many times

const result = ErrorTools.retryOr('default', 5, seconds(1), () => getSomething());
# Parameter Name Required Type Default Description
0 orValue Yes T Default value to return if the function fails
1 maxTries No number 10 Maximum number of tries
2 delay No ms 0 Delay between tries
3 run No () => T | Promise<T> fn.result(orValue) Function to run on each attempt
Return Type
Promise<T> Promise that resolves to the result of the function, or the default value if it fails after all tries

[↑ Back to ErrorTools ↑]

tryCatch

tryCatch(promiseOrFunc: Promise<T> | (() => T | Promise<T>)): Promise<TryCatchResult<T, E>>
ErrorTools.tryCatch(promiseOrFunc: Promise<T> | (() => T | Promise<T>)): Promise<TryCatchResult<T, E>>

Inspired by the tryCatch function by t3dotgg.

const getFoo = async () => {
  return 'foo';
};
const example1 = await ErrorTools.tryCatch(getFoo()); // { result: 'foo', error: null }

const getError = async () => {
  throw new Error('foo');
};
const example2 = await ErrorTools.tryCatch(getError()); // { result: null, error: Error }

const example3 = await ErrorTools.tryCatch(() => {
  return 'bar';
}); // { result: 'bar', error: null }
# Parameter Name Required Type Description
0 promiseOrFunc Yes Promise<T> | (() => T | Promise<T>) Promise or function to try
Return Type
Promise<TryCatchResult<T, E>> Promise with result or error

[↑ Back to ErrorTools ↑]

Cachier

A simple caching tool to store and retrieve values by id.

Useful for storing values that are expensive to calculate, or that you want to reuse.

[↑ Back to top ↑]

cachier

cachier;

A generic cachier object for general purpose caching.

Call cachier.create<T>() to create a new isolated cachier object with a specific type.

// Initial save
cachier.save('foo', { name: 'foo' }); // { "name": "foo" }
cachier.get('foo'); // { "name": "foo" }

// Save with expiry (expires in 5 seconds)
cachier.save('tmp1', { name: 'tmp1' }, seconds(5)); // { "name": "tmp1" }
cachier.get('tmp1'); // { "name": "tmp1" }
// After 5 seconds: cachier.get('tmp1'); // undefined

// Overwrite
cachier.save('foo', { name: 'bar' }); // { "name": "bar" }
cachier.get('foo'); // { "name": "bar" }

// Get if exists, otherwise save
cachier.getOrSave('foo', { name: 'baz' }); // { "name": "bar" }
cachier.get('foo'); // { "name": "bar" }

// Get if exists, otherwise save with expiry
cachier.getOrSave('tmp2', { name: 'tmp2' }, seconds(3)); // { "name": "tmp2" }
cachier.get('tmp2'); // { "name": "tmp2" }
// After 3 seconds: cachier.get('tmp2'); // undefined

// Get if exists, otherwise run function to create and save
cachier.getOrRun('foo', () => ({ name: 'qux' })); // { "name": "bar" }
cachier.get('foo'); // { "name": "bar" }

// Get if exists, otherwise run function with expiry
cachier.getOrRun('tmp3', () => ({ name: 'tmp3' }), seconds(2)); // { "name": "tmp3" }
cachier.get('tmp3'); // { "name": "tmp3" }
// After 2 seconds: cachier.get('tmp3'); // undefined

// Remove
cachier.remove('foo');
cachier.get('foo'); // undefined

// Populate
cachier.save('foo', { name: 'foo' }); // { "name": "foo" }
cachier.save('bar', { name: 'bar' }); // { "name": "bar" }
cachier.save('baz', { name: 'baz' }); // { "name": "baz" }

// Get all
cachier.getAll(); // { "foo": { "name": "foo" }, "bar": { "name": "bar" }, "baz": { "name": "baz" } }

// Clear
cachier.clear();
cachier.getAll(); // {}

[↑ Back to Cachier ↑]

get

cachier.get(id: string, ignoreExpiry: boolean): T
cachier.create().get(id: string, ignoreExpiry: boolean): T

Get a cached item by id.

cachier.save('foo', { name: 'foo' });
cachier.get('foo'); // { "name": "foo" }
# Parameter Name Required Type Default Description
0 id Yes string ID of the item to get
1 ignoreExpiry No boolean false If true, the item will be returned even if it has expired.
Return Type
T The cached item, or undefined if it doesn't exist or has expired

[↑ Back to Cachier ↑]

getOrSave

cachier.getOrSave(id: string, orValue: T, expiresIn: ms, ignoreExpiry: boolean): T
cachier.create().getOrSave(id: string, orValue: T, expiresIn: ms, ignoreExpiry: boolean): T

Get a cached item by id, or save a new item if it doesn't exist.

cachier.getOrSave('foo', { name: 'lorem' }); // { "name": "lorem" }
cachier.get('foo'); // { "name": "lorem" }

cachier.getOrSave('foo', { name: 'SOMETHING DIFFERENT' }); // { "name": "lorem" }
cachier.get('foo'); // { "name": "lorem" }

// With expiry (expires in 10 seconds)
cachier.getOrSave('bar', { name: 'bar' }, seconds(10)); // { "name": "bar" }
cachier.get('bar'); // { "name": "bar" }
// After 10 seconds: cachier.get('bar'); // undefined
# Parameter Name Required Type Default Description
0 id Yes string ID of the item to get or save
1 orValue Yes T Value to save if the item doesn't exist
2 expiresIn No ms getDefaultExpiresIn() Expiration time in milliseconds for the item (if saving orValue)
3 ignoreExpiry No boolean false If true, the item will be returned even if it has expired.
Return Type
T The cached item, or the orValue if it doesn't exist or has expired

[↑ Back to Cachier ↑]

getOrRun

cachier.getOrRun(id: string, orFunc: (id?: string) => T, expiresIn: ms, ignoreExpiry: boolean): T
cachier.create().getOrRun(id: string, orFunc: (id?: string) => T, expiresIn: ms, ignoreExpiry: boolean): T

Get a cached item by id, or run a function to create a new item if it doesn't exist.

The created item will be cached and returned.

cachier.getOrRun('foo', () => ({ name: 'lorem' })); // { "name": "lorem" }
cachier.get('foo'); // { "name": "lorem" }

cachier.getOrRun('foo', () => ({ name: 'SOMETHING DIFFERENT' })); // { "name": "lorem" }
cachier.get('foo'); // { "name": "lorem" }

// With expiry (expires in 15 seconds)
cachier.getOrRun('baz', () => ({ name: 'baz' }), seconds(15)); // { "name": "baz" }
cachier.get('baz'); // { "name": "baz" }
// After 15 seconds: cachier.get('baz'); // undefined
# Parameter Name Required Type Default Description
0 id Yes string ID of the item to get or run
1 orFunc Yes (id?: string) => T Function to run if the item doesn't exist. What it returns will be saved.
2 expiresIn No ms getDefaultExpiresIn() Expiration time in milliseconds for the item (if running orFunc)
3 ignoreExpiry No boolean false If true, the item will be returned even if it has expired.
Return Type
T The cached item, or the result of the orFunc if it doesn't exist or has expired

[↑ Back to Cachier ↑]

getOrRunAsync

cachier.getOrRunAsync(id: string, orFunc: (id?: string) => T | Promise<T>, expiresIn: ms, ignoreExpiry: boolean): Promise<T>
cachier.create().getOrRunAsync(id: string, orFunc: (id?: string) => T | Promise<T>, expiresIn: ms, ignoreExpiry: boolean): Promise<T>

Get a cached item by id, or run an async function to create a new item if it doesn't exist.

The created item will be cached and returned.

Same as cachier.getOrRun, but the function can be async. Return will always be a promise.

const longFn = async (name) => {
  await wait(1000);
  return { name };
};

await cachier.getOrRunAsync('foo', () => longFn('lorem')); // { name: 'lorem' }
cachier.get('foo'); // { name: 'lorem' }

await cachier.getOrRunAsync('foo', () => longFn('SOMETHING DIFFERENT')); // { name: 'lorem' }
cachier.get('foo'); // { name: 'lorem' }

// With expiry (expires in 20 seconds)
await cachier.getOrRunAsync('qux', () => longFn('qux'), seconds(20)); // { name: 'qux' }
cachier.get('qux'); // { name: 'qux' }
// After 20 seconds: cachier.get('qux'); // undefined
# Parameter Name Required Type Default Description
0 id Yes string ID of the item to get or run
1 orFunc Yes (id?: string) => T | Promise<T> Function to run if the item doesn't exist. What it returns will be saved.
2 expiresIn No ms getDefaultExpiresIn() Expiration time in milliseconds for the item (if running orFunc)
3 ignoreExpiry No boolean false If true, the item will be returned even if it has expired.
Return Type
Promise<T> Promise that resolves to the cached item, or the result of the orFunc if it doesn't exist or has expired

[↑ Back to Cachier ↑]

save

cachier.save(id: string, item: T, expiresIn: ms): T
cachier.create().save(id: string, item: T, expiresIn: ms): T

Save an item to the cache.

cachier.save('foo', { name: 'foo' }); // { "name": "foo" }
cachier.get('foo'); // { "name": "foo" }

// With expiry (expires in 30 seconds)
cachier.save('quux', { name: 'quux' }, seconds(30)); // { "name": "quux" }
cachier.get('quux'); // { "name": "quux" }
// After 30 seconds: cachier.get('quux'); // undefined
# Parameter Name Required Type Default Description
0 id Yes string ID of the item to save
1 item Yes T Item to save
2 expiresIn No ms getDefaultExpiresIn() Expiration time in milliseconds for the item
Return Type
T The saved item

[↑ Back to Cachier ↑]

remove

cachier.remove(id: string): void
cachier.create().remove(id: string): void

Remove an item from the cache.

cachier.save('foo', { name: 'foo' });
cachier.get('foo'); // { "name": "foo" }

cachier.remove('foo');
cachier.get('foo'); // undefined
# Parameter Name Required Type Description
0 id Yes string ID of the item to remove
Return Type
void

[↑ Back to Cachier ↑]

clear

cachier.clear(): void
cachier.create().clear(): void

Clear all items from the cache.

cachier.save('foo', { name: 'foo' });
cachier.getAll(); // { foo: { "name": "foo" } }

cachier.clear();
cachier.getAll(); // {}
Return Type
void

[↑ Back to Cachier ↑]

getAll

cachier.getAll(ignoreExpiry: boolean): Record<string, T>
cachier.create().getAll(ignoreExpiry: boolean): Record<string, T>

Get all items from the cache.

cachier.save('foo', { name: 'foo' });
cachier.save('bar', { name: 'bar' });
cachier.save('baz', { name: 'baz' });

cachier.getAll(); // { "foo": { "name": "foo" }, "bar": { "name": "bar" }, "baz": { "name": "baz" } }
# Parameter Name Required Type Default Description
0 ignoreExpiry No boolean false If true, the item will be returned even if it has expired.
Return Type
Record<string, T> Object of all saved items

[↑ Back to Cachier ↑]

getDefaultExpiresIn

cachier.getDefaultExpiresIn(): ms
cachier.create().getDefaultExpiresIn(): ms

Get the default expiration time for items in the cache.

cachier.getDefaultExpiresIn(); // Infinity
cachier.setDefaultExpiresIn(1000);
cachier.getDefaultExpiresIn(); // 1000
Return Type
ms Default expiration time in milliseconds

[↑ Back to Cachier ↑]

setDefaultExpiresIn

cachier.setDefaultExpiresIn(newValue: ms): ms
cachier.create().setDefaultExpiresIn(newValue: ms): ms

Set the default expiration time for items in the cache.

cachier.getDefaultExpiresIn(); // Infinity
cachier.setDefaultExpiresIn(1000);
cachier.getDefaultExpiresIn(); // 1000
# Parameter Name Required Type Default Description
0 newValue No ms Infinity New default expiration time in milliseconds
Return Type
ms New default expiration time in milliseconds

[↑ Back to Cachier ↑]

create

cachier.create<T>(defaultExpiresIn: ms): Cachier<U>
cachier.create().create<T>(defaultExpiresIn: ms): Cachier<U>

Create a new isolated cachier object with a specific type.

const numCache = cachier.create<number>();

numCache.save('bar', 123);
cachier.save('foo', { name: 'foo' });

numCache.getAll(); // { "bar": 123 }
cachier.getAll(); // { "foo": { "name": "foo" } }

// Create cache with default expiry (all items expire in 60 seconds)
const tempCache = cachier.create<string>(seconds(60));
tempCache.save('foo', 'foo'); // expires in 60 seconds
tempCache.save('bar', 'bar', seconds(5)); // overrides default, expires in 5 seconds
# Parameter Name Required Type Default Description
0 defaultExpiresIn No ms Infinity Default expiration time in milliseconds for the new cache
Return Type
Cachier<U> New cachier object

[↑ Back to Cachier ↑]

Cachier

Cachier<T>;

Type for a cachier object.

[↑ Back to Cachier ↑]

onDemand

onDemand<T>(input: OnDemandInputObject<T>): T

A way of deferring the evaluation of object properties until they are accessed.

Provide it with an object where the values are either raw values or functions that return the value, and it will give you back a new object where the values are only evaluated when accessed.

const demanded = onDemand({
  name: () => 'foo',
  random: () => Math.floor(Math.random() * 1000),
  data: () => ({lorem: 'ipsum'}),
  func: () => {
    const randomLetter1 = String.fromCharCode(65 + Math.floor(Math.random() * 26));
    return () => {
      const randomLetter2 = String.fromCharCode(65 + Math.floor(Math.random() * 26));
      return `${randomLetter1}-${randomLetter2}`;
    }
  },
  age: 30
});

// access a value
demanded.name; // 'foo'

// overwrite a value
demanded.name = 'bar';
demanded.name; // 'bar'

// getters are cached, so only execute once, and always return the same value
demanded.random // 701
demanded.random // 701
demanded.data === demanded.data // true

// getters can return functions
demanded.func(); // 'J-A'
demanded.func(); // 'J-M'
demanded.func(); // 'J-K'
demanded.func(); // 'J-S'

// You can also just provide raw values without needing a getter
demanded.age; // 30

type Example = typeof demanded; // {
  //  name: string;
  //  random: number;
  //  data: {
  //      lorem: string;
  //  };
  //  func: () => string;
  //  age: number;
  //}
# Parameter Name Required Type Description
0 input Yes OnDemandInputObject<T> Input object
Return Type
T Object where each value is only evaluated when accessed

[↑ Back to top ↑]

OnDemandInputObject

OnDemandInputObject<T>;

A type that takes an object and makes all the values either functions that return the value, or the value itself.

Input type for the onDemand function.

[↑ Back to onDemand ↑]

symbols

symbols;

A series of characters that can be used for display symbols

Name Symbol
TAB symbols.TAB
TICK symbols.TICK
CROSS symbols.CROSS
PLUS symbols.PLUS +
MINUS symbols.MINUS -
TIMES symbols.TIMES ×
DIVIDE symbols.DIVIDE ÷
ELLIPSIS symbols.ELLIPSIS
BULLET symbols.BULLET
BULLET_TRI symbols.BULLET_TRI
BULLET_HYP symbols.BULLET_HYP
EJECT symbols.EJECT
TILDE symbols.TILDE ~
HOME symbols.HOME ~
RADIO_EMPTY symbols.RADIO_EMPTY
RADIO_FULL symbols.RADIO_FULL
CURSOR symbols.CURSOR
CHEV_LFT symbols.CHEV_LFT
CHEV_RGT symbols.CHEV_RGT
CHAIN symbols.CHAIN
TRI_UPP symbols.TRI_UPP
TRI_DWN symbols.TRI_DWN
TRI_RGT symbols.TRI_RGT
TRI_LFT symbols.TRI_LFT
ARROW_UPP symbols.ARROW_UPP
ARROW_DWN symbols.ARROW_DWN
ARROW_RGT symbols.ARROW_RGT
ARROW_LFT symbols.ARROW_LFT
ARROW_UPP_RGT symbols.ARROW_UPP_RGT
ARROW_DWN_RGT symbols.ARROW_DWN_RGT
ARROW_DWN_LFT symbols.ARROW_DWN_LFT
ARROW_UPP_LFT symbols.ARROW_UPP_LFT
ARROW_STILL symbols.ARROW_STILL
ARROW_FLIP_H symbols.ARROW_FLIP_H
ARROW_FLIP_V symbols.ARROW_FLIP_V
ARROW_ROTATE_UPP symbols.ARROW_ROTATE_UPP
ARROW_ROTATE_DWN symbols.ARROW_ROTATE_DWN
ARROW_ROTATE_LFT symbols.ARROW_ROTATE_LFT
ARROW_ROTATE_RGT symbols.ARROW_ROTATE_RGT
ARROW_ROTATE_CLOCK symbols.ARROW_ROTATE_CLOCK
ARROW_ROTATE_ANTI_CLOCK symbols.ARROW_ROTATE_ANTI_CLOCK
FRACTION_1_4 symbols.FRACTION_1_4 ¼
FRACTION_1_2 symbols.FRACTION_1_2 ½
FRACTION_3_4 symbols.FRACTION_3_4 ¾
SUPERSCRIPT symbols.SUPERSCRIPT['1'] ¹
symbols.SUPERSCRIPT['2'] ²
symbols.SUPERSCRIPT['3'] ³
symbols.SUPERSCRIPT['4']
symbols.SUPERSCRIPT['5']
symbols.SUPERSCRIPT['6']
symbols.SUPERSCRIPT['7']
symbols.SUPERSCRIPT['8']
symbols.SUPERSCRIPT['9']
symbols.SUPERSCRIPT['0']
symbols.SUPERSCRIPT['-']
symbols.SUPERSCRIPT['+']
symbols.SUPERSCRIPT['=']
symbols.SUPERSCRIPT['(']
symbols.SUPERSCRIPT[')']
symbols.SUPERSCRIPT['i']
symbols.SUPERSCRIPT['n']
symbols.SUPERSCRIPT['o'] °
symbols.SUPERSCRIPT['*'] °
BLOCK symbols.BLOCK.full
symbols.BLOCK.upperHalf
symbols.BLOCK.lowerOneEighth
symbols.BLOCK.lowerOneQuarter
symbols.BLOCK.lowerThreeEighths
symbols.BLOCK.lowerHalf
symbols.BLOCK.lowerFiveEighths
symbols.BLOCK.lowerThreeQuarters
symbols.BLOCK.lowerSevenEighths
symbols.BLOCK.leftSevenEighths
symbols.BLOCK.leftThreeQuarters
symbols.BLOCK.leftFiveEighths
symbols.BLOCK.leftHalf
symbols.BLOCK.leftThreeEighths
symbols.BLOCK.leftOneQuarter
symbols.BLOCK.leftOneEighth
symbols.BLOCK.rightHalf
symbols.BLOCK.upperOneEighth
symbols.BLOCK.rightOneEighth
SHADE symbols.SHADE.light
symbols.SHADE.medium
symbols.SHADE.dark
QUADRANT symbols.QUADRANT.upperLeft
symbols.QUADRANT.upperRight
symbols.QUADRANT.lowerLeft
symbols.QUADRANT.lowerRight
symbols.QUADRANT.upperLeftLowerLeftLowerRight
symbols.QUADRANT.upperLeftLowerRight
symbols.QUADRANT.upperLeftUpperRightLowerLeft
symbols.QUADRANT.upperLeftUpperRightLowerRight
symbols.QUADRANT.upperRightLowerLeft
symbols.QUADRANT.upperRightLowerLeftLowerRight

[↑ Back to top ↑]

superscript

superscript(num: number | string): string

Converts a string or number to superscript (where possible)

Known superscript characters: ¹²³⁴⁵⁶⁷⁸⁹⁰⁻⁺⁼⁽⁾ⁱⁿ°

Characters without a superscript equivalent will be replaced with a °

superscript(219) // '²¹⁹'
superscript(1234567890) // '¹²³⁴⁵⁶⁷⁸⁹⁰'
# Parameter Name Required Type Description
0 num Yes number | string Number or string to convert to superscript
Return Type
string Superscript string

[↑ Back to symbols ↑]

queue

A way of managing queues from different parts of the code.

[↑ Back to top ↑]

QueueManager

QueueManager;

Allows you to queue up functions to be executed in order.

Importantly, it allows you to add to the queue from another part of the code, without needing to access a promise directly.

const printDocument = async (id: number) => {
  // do something
  await wait(seconds(5));
}

const queue = new QueueManager();

const start = Date.now();

// happening async/concurrently
PromiseTools.each(range(5), async (i) => {
  await wait(seconds(Math.random() * 1));
  console.log(Date.now() - start, ' - trigger:', i, );
  await queue.add('printer', () => printDocument(i))
  console.log(Date.now() - start, ' - printed:', i);
})

// Output:

// 184 ' - trigger:' 0
// 355 ' - trigger:' 2
// 435 ' - trigger:' 4
// 448 ' - trigger:' 1
// 487 ' - trigger:' 3
// 5190 ' - printed:' 0
// 10195 ' - printed:' 2
// 15200 ' - printed:' 4
// 20205 ' - printed:' 1
// 25208 ' - printed:' 3

[↑ Back to queue ↑]

setDefaultPauseTime

queue.setDefaultPauseTime(time: ms): void
new QueueManager().setDefaultPauseTime(time: ms): void

Sets the default pause time for pauses between queue items.

queue.setDefaultPauseTime(seconds(1));
# Parameter Name Required Type Description
0 time Yes ms Amount of time to pause between queue items
Return Type
void

[↑ Back to queue ↑]

setPauseTime

queue.setPauseTime(id: string, time: ms): void
new QueueManager().setPauseTime(id: string, time: ms): void

Sets the pause time for pauses between queue items for the specified queue.

queue.setPauseTime('printer', seconds(1));
# Parameter Name Required Type Description
0 id Yes string Queue ID
1 time Yes ms Amount of time to pause between queue items
Return Type
void

[↑ Back to queue ↑]

add

queue.add(id: string, promiseItem: PromiseTools.PromiseItem<T>): Promise<T>
new QueueManager().add(id: string, promiseItem: PromiseTools.PromiseItem<T>): Promise<T>

Adds a function to the queue.

queue.add('printer', async () => {
  await wait(seconds(1));
  console.log('printed');
});
# Parameter Name Required Type Description
0 id Yes string Queue ID
1 promiseItem Yes PromiseTools.PromiseItem<T> Function to add to the queue
Return Type
Promise<T> Promise that resolves to the result of the function once it has been executed

[↑ Back to queue ↑]

new

queue.new(defaultPauseTime: ms): QueueManager
new QueueManager().new(defaultPauseTime: ms): QueueManager
QueueManager.new(defaultPauseTime: ms): QueueManager

Creates a new QueueManager instance.

const newQueue = queue.new();
# Parameter Name Required Type Default Description
0 defaultPauseTime No ms 0 Amount of time to pause between queue items
Return Type
QueueManager New QueueManager instance

[↑ Back to queue ↑]

queue

queue;

An instance of QueueManager

See QueueManager for more information.

[↑ Back to queue ↑]

timer

A debug tool for measuring the duration of code blocks.

[↑ Back to top ↑]

Timer Instance

start

timer.start(...labels: string[]): void
getTimer().start(...labels: string[]): void

Start a timer

timer.start('TOTAL', 'Intro');
# Parameter Name Required Type Description
0… labels Yes string[] Labels to start
Return Type
void

[↑ Back to timer ↑]

end

timer.end(...labels: string[]): void
getTimer().end(...labels: string[]): void

End a given timer

timer.end('TOTAL', 'Intro');
# Parameter Name Required Type Description
0… labels Yes string[] Labels to end
Return Type
void

[↑ Back to timer ↑]

switch

timer.switch(endLabel: string | string[], startLabel: string | string[]): void
getTimer().switch(endLabel: string | string[], startLabel: string | string[]): void

Switch the timer The same as calling timer.end(endLabel) and timer.start(startLabel)

timer.switch('Intro', 'Ending');
# Parameter Name Required Type Description
0 endLabel Yes string | string[] Label(s) to end
1 startLabel Yes string | string[] Label(s) to start
Return Type
void

[↑ Back to timer ↑]

getTable

timer.getTable(prefix: string, customEntries: ((durations: TimerDurations<TName>) => CustomEntryObj)[] | CustomEntryDict<TimerDurations<TName>, TName>): string
getTimer().getTable(prefix: string, customEntries: ((durations: TimerDurations<TName>) => CustomEntryObj)[] | CustomEntryDict<TimerDurations<TName>, TName>): string

Get the timing table as a string

timer.getTable();
# Parameter Name Required Type Description
0 prefix No string Prefix to add to the timing table
1 customEntries No ((durations: TimerDurations<TName>) => CustomEntryObj)[] | CustomEntryDict<TimerDurations<TName>, TName> Custom entries to add to the timing table
Return Type
string the timing table

[↑ Back to timer ↑]

log

timer.log(prefix: string, customEntries: ((durations: TimerDurations<TName>) => CustomEntryObj)[] | CustomEntryDict<TimerDurations<TName>, TName>): number
getTimer().log(prefix: string, customEntries: ((durations: TimerDurations<TName>) => CustomEntryObj)[] | CustomEntryDict<TimerDurations<TName>, TName>): number

Log the timing table

timer.log();
# Parameter Name Required Type Description
0 prefix No string Prefix to add to the timing table
1 customEntries No ((durations: TimerDurations<TName>) => CustomEntryObj)[] | CustomEntryDict<TimerDurations<TName>, TName> Custom entries to add to the timing table
Return Type
number the number of lines logged

[↑ Back to timer ↑]

reset

timer.reset(): void
getTimer().reset(): void

Reset the timer

timer.reset();
Return Type
void

[↑ Back to timer ↑]

getDuration

timer.getDuration(label: string): ms
getTimer().getDuration(label: string): ms

Get the duration of a given timer

timer.getDuration('Intro');
# Parameter Name Required Type Description
0 label Yes string Label to get the duration of
Return Type
ms The duration of the timer

[↑ Back to timer ↑]

names

timer.names;
getTimer().names;

The names of the timers

timer.names; // { TOTAL: 'TOTAL', INTRO: 'Intro', ENDING: 'Ending' }

[↑ Back to timer ↑]

displayNames

timer.displayNames;
getTimer().displayNames;

The display names of the timers

timer.displayNames; // { TOTAL: 'TOTAL', INTRO: 'Intro', ENDING: 'Ending' }

[↑ Back to timer ↑]

startTimes

timer.startTimes;
getTimer().startTimes;

The start times of the timers

timer.startTimes; // { TOTAL: 1715395200000, INTRO: 1715395200000, ENDING: 1715395200000 }

[↑ Back to timer ↑]

endTimes

timer.endTimes;
getTimer().endTimes;

The end times of the timers

timer.endTimes; // { TOTAL: 1715395200000, INTRO: 1715395200000, ENDING: 1715395200000 }

[↑ Back to timer ↑]

getTimer

getTimer(name: string, verbose: boolean, wrapperFn: any, displayNames: TName): any

Usage:

const timer = getTimer('Example', false, colr.red, {
  TOTAL: 'TOTAL',
  INTRO: 'Action 1',
  ENDING: 'Action 2'
});
timer.start(timer.TOTAL, timer.INTRO);

await wait(seconds(4)); // do something async

timer.switch(timer.INTRO, timer.ENDING); // same as calling end(timer.INTRO) and start(timer.ENDING)

await wait(seconds(6)); // do something async

timer.end(timer.TOTAL, timer.ENDING);
timer.log();

Output:

Example Times:
	Action 1: 4s
	Action 2: 6s
	⎯⎯⎯⎯⎯⎯⎯
	TOTAL:    10s
# Parameter Name Required Type Default Description
0 name No string Name of the timer
1 verbose No boolean false Whether to log the timing table
2 wrapperFn No any colr.dark.white Function to wrap the timing table in
3 displayNames No TName Display names of the timers
Return Type
any The timer instance

[↑ Back to timer ↑]

timer

timer;

Usage:

timer.start('TOTAL', 'Intro');

await wait(seconds(4)); // do something async

timer.switch('Intro', 'Ending'); // same as calling timer.end('Intro') and timer.start('Ending')

await wait(seconds(6)); // do something async

timer.end('TOTAL', 'Ending');
timer.log();

Output:

Times:
	Intro:   4s
	Ending:  6s
	⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
	TOTAL:   10s

[↑ Back to timer ↑]

safe

A series of simple functions for ensuring that a value is safe to use.

Used internally for input validation.

[↑ Back to top ↑]

num

safe.num(input: number, isInt: boolean, min: number, max: number, fallback: number): number

Process a number value, ensuring that it is safe to use.

safe.num(10); // 10
safe.num(10000); // 10000
safe.num(-1); // -1
safe.num(true); // 0
safe.num('123'); // 0
safe.num(NaN); // 0
safe.num(Infinity); // 0
safe.num(null); // 0
safe.num(undefined); // 0

safe.num(10, true, 0, 100, 99); // 10
safe.num(10000, true, 0, 100, 99); // 100
safe.num(-1, true, 0, 100, 99); // 0
safe.num(true, true, 0, 100, 99); // 99
safe.num('123', true, 0, 100, 99); // 99
safe.num(NaN, true, 0, 100, 99); // 99
safe.num(Infinity, true, 0, 100, 99); // 100
safe.num(null, true, 0, 100, 99); // 99
safe.num(undefined, true, 0, 100, 99); // 99
# Parameter Name Required Type Default Description
0 input Yes number Number to process
1 isInt No boolean false Whether to force the number to be an integer
2 min No number Minimum value
3 max No number Maximum value
4 fallback No number 0 Fallback value
Return Type
number Number that is safe to use

[↑ Back to safe ↑]

str

safe.str(input: string, allowBasicStringify: boolean, fallback: string): string

Process a string value, ensuring that it is safe to use.

safe.str('foo'); // 'foo'
safe.str(''); // ''
safe.str(123); // ''
safe.str(true); // ''
safe.str({foo: 'bar'}); // ''
safe.str([]); // ''
safe.str(null); // ''
safe.str(undefined); // ''

safe.str('foo', true, 'bar'); // 'foo'
safe.str('', true, 'bar'); // ''
safe.str(123, true, 'bar'); // '123'
safe.str(true, true, 'bar'); // 'true'
safe.str({foo: 'bar'}, true, 'bar'); // 'bar'
safe.str([], true, 'bar'); // 'bar'
safe.str(null, true, 'bar'); // 'bar'
safe.str(undefined, true, 'bar'); // 'bar'
# Parameter Name Required Type Default Description
0 input Yes string String to process
1 allowBasicStringify No boolean false Whether to allow basic stringification
2 fallback No string '' Fallback value
Return Type
string String that is safe to use

[↑ Back to safe ↑]

bool

safe.bool(input: boolean, fallback: boolean): boolean

Process a boolean value, ensuring that it is safe to use.

safe.bool(true); // true
safe.bool(false); // false
safe.bool(1); // true
safe.bool(0); // false
safe.bool(123); // false
safe.bool('true'); // true
safe.bool('false'); // false
safe.bool('foobar'); // false
safe.bool({foo: 'bar'}); // false
safe.bool([]); // false
safe.bool(null); // false
safe.bool(undefined); // false

safe.bool(true, true); // true
safe.bool(false, true); // false
safe.bool(1, true); // true
safe.bool(0, true); // false
safe.bool(123, true); // true
safe.bool('true', true); // true
safe.bool('false', true); // false
safe.bool('foobar', true); // true
safe.bool({foo: 'bar'}, true); // true
safe.bool([], true); // true
safe.bool(null, true); // true
safe.bool(undefined, true); // true

|  #  | Parameter Name | Required | Type      | Default | Description        |
|:---:|:---------------|:---------|:----------|:--------|:-------------------|
| *0* | `input`        | **Yes**  | `boolean` |         | Boolean to process |
| *1* | `fallback`     | *No*     | `boolean` | `false` | Fallback value     |

| Return Type |                             |
|-------------|-----------------------------|
| `boolean`   | Boolean that is safe to use |

<p style="text-align: right" align="right"><a href="#safe"> [ Back to <b>safe</b> ] </a></p>

### <span id="safe_func">func</span>

```typescript
safe.func<T>(input: T, fallback: T): T

Process a function value, ensuring that it is safe to use.

safe.func((p: number) => 123); // (p: number) => 123
safe.func(true); // (() => {})
safe.func(false); // (() => {})
safe.func(123); // (() => {})
safe.func('foobar'); // (() => {})
safe.func({foo: 'bar'}); // (() => {})
safe.func([1, 2, 3]); // (() => {})
safe.func(null); // (() => {})
safe.func(undefined); // (() => {})

safe.func((p: number) => 123, (q: number) => 456); // (p: number) => 123
safe.func(true, (q: number) => 456); // (q: number) => 456
safe.func(false, (q: number) => 456); // (q: number) => 456
safe.func(123, (q: number) => 456); // (q: number) => 456
safe.func('foobar', (q: number) => 456); // (q: number) => 456
safe.func({foo: 'bar'}, (q: number) => 456); // (q: number) => 456
safe.func([1, 2, 3], (q: number) => 456); // (q: number) => 456
safe.func(null, (q: number) => 456); // (q: number) => 456
safe.func(undefined, (q: number) => 456); // (q: number) => 456
# Parameter Name Required Type Default Description
0 input Yes T Function to process
1 fallback No T (() => {}) as unknown as T Fallback value
Return Type
T Function that is safe to use

[↑ Back to safe ↑]

obj

safe.obj<T>(input: T, allowArrays: boolean, fallback: T): T

Process an object value, ensuring that it is safe to use.

safe.obj({foo: 'bar'}); // {foo: 'bar'}
safe.obj([1, 2, 3]); // [1, 2, 3]
safe.obj(true); // {}
safe.obj(false); // {}
safe.obj(123); // {}
safe.obj('foobar'); // {}
safe.obj(null); // {}
safe.obj(undefined); // {}

safe.obj({foo: 'bar'}, true, {baz: 123}); // {foo: 'bar'}
safe.obj([1, 2, 3], true, {baz: 123}); // [1, 2, 3]
safe.obj(true, true, {baz: 123}); // {baz: 123}
safe.obj(false, true, {baz: 123}); // {baz: 123}
safe.obj(123, true, {baz: 123}); // {baz: 123}
safe.obj('foobar', true, {baz: 123}); // {baz: 123}
safe.obj(null, true, {baz: 123}); // {baz: 123}
safe.obj(undefined, true, {baz: 123}); // {baz: 123}
# Parameter Name Required Type Default Description
0 input Yes T Object to process
1 allowArrays No boolean false Whether to allow arrays
2 fallback No T {} as T Fallback value
Return Type
T Object that is safe to use

[↑ Back to safe ↑]

objWith

safe.objWith<T>(input: T, objConfig: ObjWithConfig<T>, allowComposition: boolean): T

Process an object value, ensuring that it is safe to use, and has the neccesary properties.

You must provide a config object that defines the properties that are required, and how to process them. Each required property must have a fallback value, and can have an optional checkFn and safeFn.

  • fallback - the value to use if the property is missing or invalid
  • checkFn - a function that returns true if the property is missing or invalid (defaults to (v) => v === undefined)
  • safeFn - a function that returns the safe value to use (defaults to (v, f) => f)
const config1: ObjWithConfig<{ foo: string }> = {
  foo: {
    fallback: 'a',
    safeFn: (v, f) => safe.str(v, false, f),
  },
};
safe.objWith({foo: 'bar'}, config1); // { foo: 'bar' }
safe.objWith([1, 2, 3], config1); // { '0': 1, '1': 2, '2': 3, foo: 'a' }
safe.objWith(true, config1); // { foo: 'a' }
safe.objWith(false, config1); // { foo: 'a' }
safe.objWith(123, config1); // { foo: 'a' }
safe.objWith('foobar', config1); // { foo: 'a' }
safe.objWith(null, config1); // { foo: 'a' }
safe.objWith(undefined, config1); // { foo: 'a' }

const config2: ObjWithConfig<{ foo: string; bar: number }> = {
  ...config1,
  bar: {
    fallback: 78,
    safeFn: (v, f) => safe.num(v, true, 0, 100, f),
  },
};
safe.objWith({foo: 'bar', bar: 45}, config2); // { foo: 'bar', bar: 45 }
safe.objWith([1, 2, 3], config2); // { '0': 1, '1': 2, '2': 3, foo: 'a', bar: 78 }
safe.objWith(true, config2); // { foo: 'a', bar: 78 }
safe.objWith(false, config2); // { foo: 'a', bar: 78 }
safe.objWith(123, config2); // { foo: 'a', bar: 78 }
safe.objWith('foobar', config2); // { foo: 'a', bar: 78 }
safe.objWith(null, config2); // { foo: 'a', bar: 78 }
safe.objWith(undefined, config2); // { foo: 'a', bar: 78 }
# Parameter Name Required Type Default Description
0 input Yes T Object to process
1 objConfig Yes ObjWithConfig<T> Object safety configuration
2 allowComposition No boolean true Whether to allow composition
Return Type
T Object that is safe to use

[↑ Back to safe ↑]

arr

safe.arr<T>(input: T[], fallback: T[], minLength: number, maxLength: number): T[]

Process an array value, ensuring that it is safe to use.

safe.arr([1, 2, 3]); // [ 1, 2, 3 ]
safe.arr(true); // []
safe.arr(false); // []
safe.arr(123); // []
safe.arr('foobar'); // []
safe.arr({foo: 'bar'}); // []
safe.arr(null); // []
safe.arr(undefined); // []

safe.arr([1, 2, 3], [4, 5, 6]); // [ 1, 2, 3 ]
safe.arr(true, [4, 5, 6]); // [ 4, 5, 6 ]
safe.arr(false, [4, 5, 6]); // [ 4, 5, 6 ]
safe.arr(123, [4, 5, 6]); // [ 4, 5, 6 ]
safe.arr('foobar', [4, 5, 6]); // [ 4, 5, 6 ]
safe.arr({foo: 'bar'}, [4, 5, 6]); // [ 4, 5, 6 ]
safe.arr(null, [4, 5, 6]); // [ 4, 5, 6 ]
safe.arr(undefined, [4, 5, 6]); // [ 4, 5, 6 ]
# Parameter Name Required Type Default Description
0 input Yes T[] Array to process
1 fallback No T[] [] Fallback value
2 minLength No number 0 Minimum length
3 maxLength No number Infinity Maximum length
Return Type
T[] Array that is safe to use

[↑ Back to safe ↑]

prop

safe.prop(input: string | number | symbol, fallback: string | number | symbol): string | number

Process a value (string or number) that is expected to be used as a property name, ensuring that it is safe to use.

Equivalent to typeof value === 'number' ? safe.num(value) : safe.str(value, true, '')

safe.prop('foo'); // 'foo'
safe.prop(''); // ''
safe.prop(123); // 123
safe.prop(true); // 'true'
safe.prop({foo: 'bar'}); // ''
safe.prop([]); // ''
safe.prop(null); // ''
safe.prop(undefined); // ''

safe.prop('foo', 'bar'); // 'foo'
safe.prop('', 'bar'); // ''
safe.prop(123, 'bar'); // 123
safe.prop(true, 'bar'); // 'true'
safe.prop({foo: 'bar'}, 'bar'); // 'bar'
safe.prop([], 'bar'); // 'bar'
safe.prop(null, 'bar'); // 'bar'
safe.prop(undefined, 'bar'); // 'bar'
# Parameter Name Required Type Default Description
0 input Yes string | number | symbol Value to process
1 fallback No string | number | symbol '' Fallback value
Return Type
string | number Property name that is safe to use

[↑ Back to safe ↑]

arrOf

A series of functions for processing arrays of values.

[↑ Back to safe ↑]

num

safe.arrOf.num(input: number[], isInt: boolean, min: number, max: number, fallback: number, fallbackArr: number[], arrMinLength: number, arrMaxLength: number): number[]

Process an array of numbers, ensuring that they are safe to use.

safe.arrOf.num([1, 2, 3]); // [ 1, 2, 3 ]
safe.arrOf.num(['foo', 1, true, null, undefined, [], {}]); // [ 0, 1, 0, 0, 0, 0, 0 ]
safe.arrOf.num(true); // []
safe.arrOf.num(false); // []
safe.arrOf.num(123); // []
safe.arrOf.num('foobar'); // []
safe.arrOf.num({foo: 'bar'}); // []
safe.arrOf.num(null); // []
safe.arrOf.num(undefined); // []

safe.arrOf.num([1, 2, 3], true, 0, 100, 99, [4, 5, 6]); // [ 1, 2, 3 ]
safe.arrOf.num(['foo', 1, true, null, undefined, [], {}], true, 0, 100, 99, [4, 5, 6]); // [ 99, 1, 99, 99, 99, 99, 99 ]
safe.arrOf.num(true, true, 0, 100, 99, [4, 5, 6]); // [ 4, 5, 6 ]
safe.arrOf.num(false, true, 0, 100, 99, [4, 5, 6]); // [ 4, 5, 6 ]
safe.arrOf.num(123, true, 0, 100, 99, [4, 5, 6]); // [ 4, 5, 6 ]
safe.arrOf.num('foobar', true, 0, 100, 99, [4, 5, 6]); // [ 4, 5, 6 ]
safe.arrOf.num({foo: 'bar'}, true, 0, 100, 99, [4, 5, 6]); // [ 4, 5, 6 ]
safe.arrOf.num(null, true, 0, 100, 99, [4, 5, 6]); // [ 4, 5, 6 ]
safe.arrOf.num(undefined, true, 0, 100, 99, [4, 5, 6]); // [ 4, 5, 6 ]
# Parameter Name Required Type Default Description
0 input Yes number[] Array of numbers to process
1 isInt No boolean false Whether to force the numbers to be integers
2 min No number Minimum number value
3 max No number Maximum number value
4 fallback No number Fallback number value
5 fallbackArr No number[] [] Fallback array
6 arrMinLength No number 0 Minimum length of the array
7 arrMaxLength No number Infinity Maximum length of the array
Return Type
number[] Array of numbers that is safe to use

[↑ Back to safe ↑]

str

safe.arrOf.str(input: string[], allowStringify: boolean, fallback: string, fallbackArr: string[], arrMinLength: number, arrMaxLength: number): string[]

Process an array of strings, ensuring that they are safe to use.

safe.arrOf.str(['foo', 'bar', 'baz']); // [ 'foo', 'bar', 'baz' ]
safe.arrOf.str(['foo', 1, true, null, undefined, [], {}]); // [ 'foo', '', '', '', '', '', '' ]
safe.arrOf.str(true); // []
safe.arrOf.str(false); // []
safe.arrOf.str(123); // []
safe.arrOf.str('foobar'); // []
safe.arrOf.str({foo: 'bar'}); // []
safe.arrOf.str(null); // []
safe.arrOf.str(undefined); // []

safe.arrOf.str(['foo', 'bar', 'baz'], true, 'LOREM', ['IPSUM']); // [ 'foo', 'bar', 'baz' ]
safe.arrOf.str(['foo', 1, true, null, undefined, [], {}], true, 'LOREM', ['IPSUM']); // [ 'foo', '1', 'true', 'LOREM', 'LOREM', 'LOREM', 'LOREM' ]
safe.arrOf.str(true, true, 'LOREM', ['IPSUM']); // [ 'IPSUM' ]
safe.arrOf.str(false, true, 'LOREM', ['IPSUM']); // [ 'IPSUM' ]
safe.arrOf.str(123, true, 'LOREM', ['IPSUM']); // [ 'IPSUM' ]
safe.arrOf.str('foobar', true, 'LOREM', ['IPSUM']); // [ 'IPSUM' ]
safe.arrOf.str({foo: 'bar'}, true, 'LOREM', ['IPSUM']); // [ 'IPSUM' ]
safe.arrOf.str(null, true, 'LOREM', ['IPSUM']); // [ 'IPSUM' ]
safe.arrOf.str(undefined, true, 'LOREM', ['IPSUM']); // [ 'IPSUM' ]
# Parameter Name Required Type Default Description
0 input Yes string[] Array of strings to process
1 allowStringify No boolean false Whether to allow stringification
2 fallback No string Fallback string value
3 fallbackArr No string[] [] Fallback array
4 arrMinLength No number 0 Minimum length of the array
5 arrMaxLength No number Infinity Maximum length of the array
Return Type
string[] Array of strings that is safe to use

[↑ Back to safe ↑]

bool

safe.arrOf.bool(input: boolean[], fallback: boolean, fallbackArr: boolean[], arrMinLength: number, arrMaxLength: number): boolean[]

Process an array of booleans, ensuring that they are safe to use.

safe.arrOf.bool([false, true, false]); // [ false, true, false ]
safe.arrOf.bool(['foo', 123, true, null, undefined, [], {}]); // [ false, false, true, false, false, false, false ]
safe.arrOf.bool(true); // []
safe.arrOf.bool(false); // []
safe.arrOf.bool(123); // []
safe.arrOf.bool('foobar'); // []
safe.arrOf.bool({foo: 'bar'}); // []
safe.arrOf.bool(null); // []
safe.arrOf.bool(undefined); // []

safe.arrOf.bool([false, true, false], true, [true, true]); // [ false, true, false ]
safe.arrOf.bool(['foo', 123, true, null, undefined, [], {}], true, [true, true]); // [ true, true, true, true, true, true, true ]
safe.arrOf.bool(true, true, [true, true]); // [ true, true ]
safe.arrOf.bool(false, true, [true, true]); // [ true, true ]
safe.arrOf.bool(123, true, [true, true]); // [ true, true ]
safe.arrOf.bool('foobar', true, [true, true]); // [ true, true ]
safe.arrOf.bool({foo: 'bar'}, true, [true, true]); // [ true, true ]
safe.arrOf.bool(null, true, [true, true]); // [ true, true ]
safe.arrOf.bool(undefined, true, [true, true]); // [ true, true ]
# Parameter Name Required Type Default Description
0 input Yes boolean[] Array of booleans to process
1 fallback No boolean Fallback boolean value
2 fallbackArr No boolean[] [] Fallback array
3 arrMinLength No number 0 Minimum length of the array
4 arrMaxLength No number Infinity Maximum length of the array
Return Type
boolean[] Array of booleans that is safe to use

[↑ Back to safe ↑]

func

safe.arrOf.func<T>(input: T[], fallback: T, fallbackArr: T[], arrMinLength: number, arrMaxLength: number): T[]

Process an array of functions, ensuring that they are safe to use.

safe.arrOf.func([(p) => 1]); // [(p) => 1]
safe.arrOf.func(['foo', 1, true, null, undefined, [], {}]); // [() => {}, () => {}, () => {}, () => {}, () => {}, () => {}, () => {}]
safe.arrOf.func(true); // []
safe.arrOf.func(false); // []
safe.arrOf.func(123); // []
safe.arrOf.func('foobar'); // []
safe.arrOf.func({foo: 'bar'}); // []
safe.arrOf.func(null); // []
safe.arrOf.func(undefined); // []

safe.arrOf.func([(p) => 1], (q) => 2, [(r) => 3]); // [(p) => 1]
safe.arrOf.func(['foo', 1, true, null, undefined, [], {}], (q) => 2, [(r) => 3]); // [(q) => 2, (q) => 2, (q) => 2, (q) => 2, (q) => 2, (q) => 2, (q) => 2]
safe.arrOf.func(true, (q) => 2, [(r) => 3]); //  [(r) => 3]
safe.arrOf.func(false, (q) => 2, [(r) => 3]); //  [(r) => 3]
safe.arrOf.func(123, (q) => 2, [(r) => 3]); //  [(r) => 3]
safe.arrOf.func('foobar', (q) => 2, [(r) => 3]); //  [(r) => 3]
safe.arrOf.func({foo: 'bar'}, (q) => 2, [(r) => 3]); //  [(r) => 3]
safe.arrOf.func(null, (q) => 2, [(r) => 3]); //  [(r) => 3]
safe.arrOf.func(undefined, (q) => 2, [(r) => 3]); //  [(r) => 3]
# Parameter Name Required Type Default Description
0 input Yes T[] Array of functions to process
1 fallback No T Fallback function value
2 fallbackArr No T[] [] Fallback array
3 arrMinLength No number 0 Minimum length of the array
4 arrMaxLength No number Infinity Maximum length of the array
Return Type
T[] Array of functions that is safe to use

[↑ Back to safe ↑]

obj

safe.arrOf.obj<T>(input: T[], allowArrays: boolean, fallback: T, fallbackArr: T[], arrMinLength: number, arrMaxLength: number): T[]

Process an array of objects, ensuring that they are safe to use.

safe.arrOf.obj([{foo: 1}, {bar: 2}]); // [ { foo: 1 }, { bar: 2 } ]
safe.arrOf.obj(['foo', 1, true, null, undefined, [], {}]); // [ {}, {}, {}, {}, {}, [], {} ]
safe.arrOf.obj(true); // []
safe.arrOf.obj(false); // []
safe.arrOf.obj(123); // []
safe.arrOf.obj('foobar'); // []
safe.arrOf.obj({foo: 'bar'}); // []
safe.arrOf.obj(null); // []
safe.arrOf.obj(undefined); // []

safe.arrOf.obj([{foo: 1}, {bar: 2}], true, {l: 3}, [{i: 4}]); // [ { foo: 1 }, { bar: 2 } ]
safe.arrOf.obj(['foo', 1, true, null, undefined, [], {}], true, {l: 3}, [{i: 4}]); // [ { l: 3 }, { l: 3 }, { l: 3 }, { l: 3 }, { l: 3 }, [], { } ]
safe.arrOf.obj(true, true, {l: 3}, [{i: 4}]); // [ { i: 4 } ]
safe.arrOf.obj(false, true, {l: 3}, [{i: 4}]); // [ { i: 4 } ]
safe.arrOf.obj(123, true, {l: 3}, [{i: 4}]); // [ { i: 4 } ]
safe.arrOf.obj('foobar', true, {l: 3}, [{i: 4}]); // [ { i: 4 } ]
safe.arrOf.obj({foo: 'bar'}, true, {l: 3}, [{i: 4}]); // [ { i: 4 } ]
safe.arrOf.obj(null, true, {l: 3}, [{i: 4}]); // [ { i: 4 } ]
safe.arrOf.obj(undefined, true, {l: 3}, [{i: 4}]); // [ { i: 4 } ]
# Parameter Name Required Type Default Description
0 input Yes T[] Array of objects to process
1 allowArrays No boolean false Whether to allow arrays
2 fallback No T Fallback object value
3 fallbackArr No T[] [] Fallback array
4 arrMinLength No number 0 Minimum length of the array
5 arrMaxLength No number Infinity Maximum length of the array
Return Type
T[] Array of objects that is safe to use

[↑ Back to safe ↑]

objWith

safe.arrOf.objWith<T>(input: T[], objConfig: ObjWithConfig<T>, allowComposition: boolean, fallbackArr: T[], arrMinLength: number, arrMaxLength: number): T[]

Process an array of objects, ensuring that they are safe to use, and have the neccesary properties.

const config1: ObjWithConfig<{ foo: string }> = {
  foo: {
    fallback: 'a',
    safeFn: (v, f) => safe.str(v, false, f)
  }
};
safe.arrOf.objWith([{ foo: 1 }, { bar: 2 }], config1); // [ { foo: 'a' }, { bar: 2, foo: 'a' } ]
safe.arrOf.objWith(['foo', 1, true, null, undefined, [], {}], config1); // [{ foo: 'a' },{ foo: 'a' },{ foo: 'a' },{ foo: 'a' },{ foo: 'a' },{ foo: 'a' },{ foo: 'a' }]
safe.arrOf.objWith(true, config1); // []
safe.arrOf.objWith(false, config1); // []
safe.arrOf.objWith(123, config1); // []
safe.arrOf.objWith('foobar', config1); // []
safe.arrOf.objWith({ foo: 'bar' }, config1); // []
safe.arrOf.objWith(null, config1); // []

const config2: ObjWithConfig<{ foo: string, bar: number }> = {
  ...config1,
  bar: {
    fallback: 78,
    safeFn: (v, f) => safe.num(v, true, 0, 100, f)
  }
};
safe.arrOf.objWith([{ foo: 1 }, { bar: 2 }], config2); // [ { foo: 'a', bar: 78 }, { bar: 2, foo: 'a' } ]
safe.arrOf.objWith(['foo', 1, true, null, undefined, [], {}], config2); // [{ foo: 'a', bar: 78 },{ foo: 'a', bar: 78 },{ foo: 'a', bar: 78 },{ foo: 'a', bar: 78 },{ foo: 'a', bar: 78 },{ foo: 'a', bar: 78 },{ foo: 'a', bar: 78 }]
safe.arrOf.objWith(true, config2); // []
safe.arrOf.objWith(false, config2); // []
safe.arrOf.objWith(123, config2); // []
safe.arrOf.objWith('foobar', config2); // []
safe.arrOf.objWith({ foo: 'bar' }, config2); // []
safe.arrOf.objWith(null, config2); // []
# Parameter Name Required Type Default Description
0 input Yes T[] Array of objects to process
1 objConfig Yes ObjWithConfig<T> Object safety configuration
2 allowComposition No boolean true Whether to allow composition
3 fallbackArr No T[] [] Fallback array
4 arrMinLength No number 0 Minimum length of the array
5 arrMaxLength No number Infinity Maximum length of the array
Return Type
T[] Array of objects that is safe to use

[↑ Back to safe ↑]

arr

safe.arrOf.arr<T>(input: T[][], fallback: T[], fallbackArr: T[][], arrMinLength: number, arrMaxLength: number): T[][]

Process an array of arrays, ensuring that they are safe to use.

safe.arrOf.arr([['foo'], ['bar']]); // [ [ 'foo' ], [ 'bar' ] ]
safe.arrOf.arr(['foo', 1, true, null, undefined, [], {}]); // [ [], [], [], [], [], [], [] ]
safe.arrOf.arr(true); // []
safe.arrOf.arr(false); // []
safe.arrOf.arr(123); // []
safe.arrOf.arr('foobar'); // []
safe.arrOf.arr({foo: 'bar'}); // []
safe.arrOf.arr(null); // []
safe.arrOf.arr(undefined); // []

safe.arrOf.arr([['foo'], ['bar']], ['baz'], [['IPSUM']]); // [ [ 'foo' ], [ 'bar' ] ]
safe.arrOf.arr(['foo', 1, true, null, undefined, [], {}], ['baz'], [['IPSUM']]); // [ [ 'baz' ], [ 'baz' ], [ 'baz' ], [ 'baz' ], [ 'baz' ], [], [ 'baz' ] ]
safe.arrOf.arr(true, ['baz'], [['IPSUM']]); // [ [ 'IPSUM' ] ]
safe.arrOf.arr(false, ['baz'], [['IPSUM']]); // [ [ 'IPSUM' ] ]
safe.arrOf.arr(123, ['baz'], [['IPSUM']]); // [ [ 'IPSUM' ] ]
safe.arrOf.arr('foobar', ['baz'], [['IPSUM']]); // [ [ 'IPSUM' ] ]
safe.arrOf.arr({foo: 'bar'}, ['baz'], [['IPSUM']]); // [ [ 'IPSUM' ] ]
safe.arrOf.arr(null, ['baz'], [['IPSUM']]); // [ [ 'IPSUM' ] ]
safe.arrOf.arr(undefined, ['baz'], [['IPSUM']]); // [ [ 'IPSUM' ] ]
# Parameter Name Required Type Default Description
0 input Yes T[][] Array of arrays to process
1 fallback No T[] Fallback array
2 fallbackArr No T[][] [] Fallback array
3 arrMinLength No number 0 Minimum length of the array
4 arrMaxLength No number Infinity Maximum length of the array
Return Type
T[][] Array of arrays that is safe to use

[↑ Back to safe ↑]

prop

safe.arrOf.prop(input: (string | number | symbol)[], fallback: string | number | symbol, fallbackArr: (string | number | symbol)[], arrMinLength: number, arrMaxLength: number): (string | number)[]

Process an array of values that can be used as properties (string or number), ensuring that they are safe to use.

safe.arrOf.prop([['foo'], ['bar']]); // [ '', '' ]
safe.arrOf.prop(['foo', 1, true, null, undefined, [], {}]); // [ 'foo', 1, 'true', '', '', '', '' ]
safe.arrOf.prop(true); // []
safe.arrOf.prop(false); // []
safe.arrOf.prop(123); // []
safe.arrOf.prop('foobar'); // []
safe.arrOf.prop({foo: 'bar'}); // []
safe.arrOf.prop(null); // []
safe.arrOf.prop(undefined); // []

safe.arrOf.prop([['foo'], ['bar']], ['baz'], ['IPSUM']); // [ [ 'baz' ], [ 'baz' ] ]
safe.arrOf.prop(['foo', 1, true, null, undefined, [], {}], ['baz'], ['IPSUM']); // [ 'foo', 1, 'true', [ 'baz' ], [ 'baz' ], [ 'baz' ],[ 'baz' ] ]
safe.arrOf.prop(true, ['baz'], ['IPSUM']); // [ 'IPSUM' ]
safe.arrOf.prop(false, ['baz'], ['IPSUM']); // [ 'IPSUM' ]
safe.arrOf.prop(123, ['baz'], ['IPSUM']); // [ 'IPSUM' ]
safe.arrOf.prop('foobar', ['baz'], ['IPSUM']); // [ 'IPSUM' ]
safe.arrOf.prop({foo: 'bar'}, ['baz'], ['IPSUM']); // [ 'IPSUM' ]
safe.arrOf.prop(null, ['baz'], ['IPSUM']); // [ 'IPSUM' ]
safe.arrOf.prop(undefined, ['baz'], ['IPSUM']); // [ 'IPSUM' ]
# Parameter Name Required Type Default Description
0 input Yes (string | number | symbol)[] Array of values to process
1 fallback No string | number | symbol Fallback property value
2 fallbackArr No (string | number | symbol)[] [] Fallback array
3 arrMinLength No number 0 Minimum length of the array
4 arrMaxLength No number Infinity Maximum length of the array
Return Type
(string | number)[] Array of property names that is safe to use

[↑ Back to safe ↑]

ObjWithConfig

safe.ObjWithConfig;

A type for defining the configuration of an object when using safe.objWith.

[↑ Back to safe ↑]

ObjWithPropConfig

safe.ObjWithPropConfig;

A type for defining what is required for a property of an object when using safe.objWith.

[↑ Back to safe ↑]

Types

Some commonly used typescript types

[↑ Back to top ↑]

Prettify

Prettify<T>;

Makes joined types more readable

type A = {name: string};
type B = {age: number};

type NormalAB = A & B; // A & B
type PrettyAB = Prettify<A & B>; // {name: string; age: number;}

[↑ Back to Types ↑]

Partial

Partial<T>;

Makes all properties in T optional.

interface ITest {
  a: string,
  b: boolean
};
type PartialTest = Partial<ITest>; // { a?: string, b?: boolean }

[↑ Back to Types ↑]

DeepPartial

DeepPartial<T>;

Like Partial, but makes all nested properties optional

interface ITest {
  a: string;
  b: {
    foo: number;
  };
  c: boolean;
};
type DeepPartialTest = DeepPartial<ITest>; // { a?: string, b?: { foo?: number }, c?: boolean }

[↑ Back to Types ↑]

KeysOnly

KeysOnly<T>;

Makes all the values equal to the keys of T

interface ITest {
  a: string,
  b: boolean
};
type KeysOnlyTest = KeysOnly<ITest>; // { a: 'a', b: 'b' }

[↑ Back to Types ↑]

Numbered

Numbered<T>;

Makes all the values numbers

interface ITest {
  a: string,
  b: boolean
};
type NumberedTest = Numbered<ITest>; // { a: number, b: number }

[↑ Back to Types ↑]

OfType<O, T>

OfType<O, T>;

Makes all the properties of object O have type T

Note: This is the same as RemapOf<O, T>

interface IExample {
  a: string;
  b: boolean;
}
OfType<IExample, number>; // { a: number; b: number; }

[↑ Back to Types ↑]

ObjOfType

ObjOfType<T>;

An object with any properties of type T

type Example = [number, number];
ObjOfType<Example>; // { [key: string]: Example; }

[↑ Back to Types ↑]

RemapOf<O, T>

RemapOf<O, T>;

Remap a given interface (O) with all properties of type T

Note: This is the same as OfType<O, T>

interface IExample {
  a: string;
  b: boolean;
}
RemapOf<IExample, number>; // { a: number; b: number; }

[↑ Back to Types ↑]

Notes

Over 9000 unit tests

[↑ Back to top ↑]