npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@usefultools/utils

v6.3.1

Published

A collection of light-weight methods and helpers for defensive programming

Downloads

8,641

Readme

CircleCI codecov npm version GuardRails Security Responsible Disclosure

JavaScript / TypeScript Utilities

A collection of light-weight methods and helpers for defensive programming.

Prereqs & Install

  • Node >=9.10.0
  • npm >=6.1.0

Please note that the TypeScript target is ES6.

npm install @usefultools/utils

Usage

There are 6 main modules available:

Async

Available methods:

  • withTimeout
  • timeout
  • makeRecoverable

Examples

withTimeout

The below will resolve source after 750ms.

function findUserById(id: number) {
  const source = () => http.get(`/api/users/${id}`)
  return withTimeout(source, 750)
}

timeout

The below will reject if asyncOperation takes more than 0.5 seconds.

function work() {
  const source = asyncOperation() // can take 0-2 seconds
  return timeout(source, 500)
}

makeRecoverable

The below will retry 5 times.

function getUsers() {
  const source = () => http.get("/api/users")
  return makeRecoverable(source, 5)
}

The below will retry 3 times, each time with a delay of 250ms.

function getUsers() {
  const source = () => http.get("/api/users")
  return makeRecoverable(source, 3, 250)
}

The below will retry thrice if the error caught is a SyntaxError.

function initService() {
  const source = () => service.init()
  return makeRecoverable(source, 3, 0, SyntaxError)
}

Full test Docs here.


Conditionals

Available methods:

  • isNull
  • isUndefined
  • isMissing
  • isPresent
  • isBoolean
  • isArray
  • isObject
  • isString
  • isNumber
  • isInteger
  • isFunction
  • isNonEmptyString
  • isNonEmptyArray
  • isTrue
  • isFalse
  • isPositiveInteger
  • isNonNegativeInteger
  • hasOneItem
  • hasMultipleItems
  • isConstructable
  • hasOnlyKeys
  • isEqual

Examples

isNull

Find out whether value is null

isNull(null) // true

isNull(undefined) // false
isNull(0) // false
isNull(NaN) // false

isUndefined

Find out whether type of value is undefined

isUndefined(undefined) // true

isUndefined(null) // false
isUndefined(0) // false

isMissing

Find out whether value is null or undefined, therefore "missing"

isMissing(null) // true
isMissing(undefined) // true

isMissing(0) // false
isMissing(NaN) // false
isMissing("") // false

isPresent

Find out whether value is not null and not undefined, therefore "present"

isPresent(0) // true
isPresent(NaN) // true
isPresent("") // true

isPresent(null) // false
isPresent(undefined) // false

isBoolean

Find out whether value is of type Boolean

isBoolean(true) // true
isBoolean(false) // true

isBoolean(0) // false

isArray

Find out whether value is of type Array

isArray([]) // true
isArray([null, undefined]) // true

isArray({}) // false

isObject

Find out whether value is of type Object

isObject({}) // true

isObject(new Function()) // false
isObject([]) // false

isString

Find out whether value is of type String

isString("") // true

isString(new String()) // false

isNumber

Find out whether value is of type Number

isNumber(42) // true
isNumber(Math.PI) // true
isNumber(Infinity) // true

isNumber(NaN) // false

isInteger

Find out whether value is of type Number and is an Integer

isInteger(42) // true

isInteger(Math.PI) // false
isInteger(Infinity) // false
isInteger(NaN) // false

isFunction

Find out whether value is of type Function

isFunction(() => {}) // true
isFunction(ReferenceError) // true

isFunction(new ReferenceError()) // false

isNonEmptyString

Find out whether value is of type String, and has at least 1 character

isNonEmptyString("Hello, World!") // true

isNonEmptyString("") // false

isNonEmptyArray

Find out whether value is of type Array and has at least one element

isNonEmptyArray([null]) // true

isNonEmptyArray([]) // false

isTrue

Find out whether value is of type Boolean and is true

isTrue(true) // true

isTrue(1) // false
isTrue(false) // false

isFalse

Find out whether value is of type Boolean and is false

isFalse(false) // true

isFalse(0) // false
isFalse(true) // false

isPositiveInteger

Find out whether value is an Integer and greater than 0

isPositiveInteger(42) // true

isPositiveInteger(0) // false
isPositiveInteger(-42) // false

isNonNegativeInteger

Find out whether value is an Integer and greater or equal to 0

isNonNegativeInteger(42) // true
isNonNegativeInteger(0) // true

isNonNegativeInteger(-42) // false

hasOneItem

Find out whether value is an Array and its length is 1

hasOneItem([null]) // true

hasOneItem([]) // false
hasOneItem([42, Math.PI]) // false

hasMultipleItems

Find out whether value is an Array and its length is more than 1

hasMultipleItems([42, Infinity]) // true

hasMultipleItems([]) // false
hasMultipleItems(["Hello, World"]) // false

isConstructable

Find out whether value is Constructable

isConstructable(new Function()) // true
isConstructable(function a() {}) // true
isConstructable(class {}) // true
isConstructable(class ClassName {}) // true

isConstructable(() => {}) // false

hasOnlyKeys

Find out whether value has only the keys provided

hasOnlyKeys({ a: "b", c: "d" }, ["a", "c"]) // true
hasOnlyKeys({ a: "b" }, ["a"]) // true
hasOnlyKeys({}, []) // true

hasOnlyKeys({ a: "b" }, ["c"]) // false
hasOnlyKeys({ a: "b", c: "d" }, ["a"]) // false

isEqual

Find out whether value 1 and value 2 are equal (shallow)

isEqual("Hello, World!", "Hello, World!") // true
isEqual(null, null) // true
isEqual(false, false) // true
isEqual(Math.PI, Math.PI) // true
isEqual(Infinity, Infinity) // true

isEqual([], []) // false
isEqual({}, {}) // false
isEqual(false, true) // false

Full test Docs here.


Env

Available methods:

  • getAsBool
  • getAsInt
  • getAsStr

NOTE: These methods are namespaced under env. The usage is therefore

import { env } from "@usefultools/utils"

env.getAsBool(...)
env.getAsInt(...)
env.getAsStr(...)

Examples

Assuming your process.env has loaded the following .env.

IS_PROD=true
ASYNC_MAX_TIMEOUT=2500
API_KEY=0351f02f-0be2-49d1-bfed-5c45275d4fd2

env.getAsBool

To retrieve the Boolean value of "IS_PROD" from process.env, you can use the following method.

env.getAsBool("IS_PROD") // true

If the raw value cannot be found, or the parsed value is not a Boolean, this function will throw a ReferenceError or a TypeError respectively.

env.getAsInt

To retrieve the Integer value of "ASYNC_MAX_TIMEOUT" from process.env, you can use the following method.

env.getAsInt("ASYNC_MAX_TIMEOUT") // 2500

If the raw value cannot be found, or the parsed value is not an Integer, this function will throw a ReferenceError or a TypeError respectively.

env.getAsStr

To retrieve the String value of "API_KEY" from process.env, you can use the following method.

env.getAsStr("API_KEY") // "0351f02f-0be2-49d1-bfed-5c45275d4fd2"

If the raw value cannot be found, this function will throw a ReferenceError.

In all of the above, you can also use your own env object like so:

// const env = { "IS_DEV": "false" }

env.getAsBool("IS_DEV", env) // false

Full test Docs here.


Helpers

Available methods:

  • noop
  • identity
  • getRandomIntInclusive
  • generateId
  • isValidId
  • generateUUID
  • isValidUUID
  • fill

Examples

noop

Sometimes you might want to provide a default callback parameter to some of your functions to prevent the application from crashing (on the off-chance someone or something accidentally calls them without any parameters). You can use the noop helper as shown below.

function doSomething(cb = noop) {
  let res: string

  try {
    await http.get("/api/healthcheck")
    res = "All works!"
  } catch (_err) {
    res = "There was an error!"
  }

  cb(res)
}

identity

Let's assume that doSomething prints its result (String) into the console, but applies onSuccess for a Ok result, and onError for a Err result. You might want to uppercase the success result, but leave the error message in its original form. You can use the identity helper as shown below.

function onSuccess(res: string) {
   return res.toUpperCase()
}

doSomething(onSuccess, identity)

getRandomIntInclusive

To get a random integer within a specified range, you can use the following:

getRandomIntInclusive(10, 99) // Yields integers between 10 and 99

generateId

To get a random id (underlying is the shortid library) use:

generateId() // "HJ5fy5p3G"
generateId() // "Byij0Ka3z"

isValidId

To confirm whether a value is a valid id (underlying is the shortid library) use:

isValidId("HJ5fy5p3G") // true
isValidId("foo") // false

generateUUID

To get a random UUID v4 (underlying is the uuid library) use:

generateUUID() // "b98c5086-1dcc-4822-9fa4-8f343f18e8de"
generateUUID() // "7118f7d9-70b1-4cb2-97da-3fe272bed7e8"

isValidId

To confirm whether a value is a valid UUID v4 (underlying is the uuid library) use:

isValidUUID("1ad006bf-00c0-49de-bcf0-7c5eb2f83241") // true
isValidUUID("foo") // false

fill

To fill an array, use:

fill(4) // [0, 1, 2, 3]

Full test Docs here.


Match

Available methods:

  • match

Other exports:

  • _def

Examples

match

A basic pattern match:

const getMessage = (year: number): string => match(year)({
  [1984]: "The year is 1984.",
  [_def]: "Unfortunately, we cannot tell what year it is."
})

getMessage(1984) // "The year is 1984."
getMessage(1994) // "Unfortunately, we cannot tell what year it is."
getMessage(2024) // "Unfortunately, we cannot tell what year it is."

Advanced pattern matching, including assertions:

function isFutureYear(year) {
  return isPositiveInteger(year)
  && year > new Date().getFullYear()
}

function isCurrentYear(year) {
  return isPositiveInteger(year)
  && year === new Date().getFullYear()
}

const getMessage = (year: number): string => match(year)(
  [1984, "The year is 1984."],
  [isCurrentYear, x => `The year ${x} is up-to-date.`],
  [isFutureYear, x => `The year ${x} is in the future...`],
  [_def, "Unfortunately, we cannot tell what year it is."],
)

getMessage(1984) // "The year is 1984."
getMessage(2018) // "The year 2018 is up-to-date."
getMessage(2024) // "The year 2024 is in the future..."
getMessage(1333) // "Unfortunately, we cannot tell what year it is."

Full test Docs here.


ThrowIf

A collection of simple throwable assertions, all of which throw if the assertion fails.

Available methods:

  • throwIfMissing
  • throwIfPresent
  • throwIfNotBoolean
  • throwIfNotArray
  • throwIfNotObject
  • throwIfNotString
  • throwIfNotNumber
  • throwIfNotInteger
  • throwIfNotFunction
  • throwIfFalse
  • throwIfEmptyString
  • throwIfEmptyArray
  • throwIfNotPositiveInteger
  • throwIfNegativeInteger
  • throwIfNotConstructable

Examples

throwIfNotObject({}); // void
throwIfNotObject([]); // throws Error
throwIfNotObject(null); // throws Error
throwIfNotObject(undefined); // throws Error

You can also provide your own error messages, and errors.

throwIfMissing(someValue, '`someValue` missing!'); // throws Error('`someValue` missing!')
throwIfMissing(someValue, '`someValue` missing!', ReferenceError); // throws ReferenceError('`someValue` missing!')

Full test Docs here.


Development

  1. Install dependencies:
npm install
  1. Compile:
make compile
  1. Test:
make test # watch mode
make test-ci # CI mode / single run
  1. Format the codebase:
make format

Contributing

If you have comments, complaints, or ideas for improvements, feel free to open an issue or a pull request! See Contributing guide for details about project setup, testing, etc.

Author and license

This library was created by @LITCHI.IO. Main author and maintainer is Slavo Vojacek.

Contributors: Slavo Vojacek

@usefultools/utils is available under the ISC license. See the LICENSE file for more info.