@jsepia/utils

1.5.2 • Public • Published

Util

Build Status Coverage Status NPM version

My utility library. Because some wheels still need to be reinvented.

Utilities

Feature detection

isBrowser

import {isBrowser} from '@jsepia/utils'

if (isBrowser()) {
  document.createElement('canvas')
}

ID

IDGenerator

import {IDGenerator} from '@jsepia/utils'

const catIDGenerator = new IDGenerator()
const dogIDGenerator = new IDGenerator()

function createCat(name) {
  return {
    id: catIDGenerator.generateID()
    name: name,
    toy: 'scratcher'
  }
}

function createDog(name) {
  return {
    id: dogIDGenerator.generateID()
    name: name,
    toy: 'ball'
  }
}

generate-id

import {generateID} from '@jsepia/utils'

const entities = []

function spawnMonster() {
  entities[generateID()] = new Monster()
}

function spawnNPC() {
  entities[generateID()] = new NPC()
}

function getEntityType(id) {
  if (entities[id] instanceof Monster) {
    return 'monster'
  }
  else if (entities[id] instanceof NPC) {
    return 'npc'
  }
  return 'unknown'
}

Object

deepExtend

Recursively merges the properties of an object into another.

import {deepExtend} from '@jsepia/utils'

const defaults = {
  targets: {
    'app.js': 'src/**/*.js',
    'tests.js': 'test/**/*.js'
  },
  verbose: false
}

const userPreferences = {
  targets: {
    'libs.js': 'lib/**/*.js'
  }
}

const commandLineParams = {
  verbose: true
}

const options = deepExtend(defaults, userPreferences, commandLineParams)

Output:

{
  "targets": {
    "app.js": "src/**/*.js",
    "tests.js": "test/**/*.js",
    "libs.js": "lib/**/*.js",
  },
  "verbose": true
}

extend

Overrides the top-level properties of an object with another's.

import {extend} from '@jsepia/utils'

const config = {
  env: 'development',
  entry: ['app.js', 'test.js']
}

const params = {
  env: 'production',
  entry: 'lib/**/*.js'
}

const options = extend(config, params)

Output:

{
  "env": "production",
  "entry": "lib/**/*.js"
}

String

indexOfRegex

import {indexOfRegex} from '@jsepia/utils'

indexOfRegex('umm', /m/g)    // 1
indexOfRegex('umm', /m/g, 2) // 2

lastIndexOfRegex

Finds the index at the last occurrence of a regular expression.

import {lastIndexOfRegex} from '@jsepia/utils'

lastIndexOfRegex('umm', /m/g)    // 2
lastIndexOfRegex('umm', /m/g, 2) // 1

Type checking

isArray

Determines whether a value is an array.

import {isArray} from '@jsepia/utils'

isArray([]) // true
isArray({}) // false
isArray('') // false

isDefined

import {isDefined} from '@jsepia/utils'

isDefined(null) // true
isDefined(undefined) // false

const kitty = {
  ears: 2,
  paws: 4,
  status: 'cute'
}
isDefined(kitty.status) // true
isDefined(kitty.wings)  // false

isIterable

import {isIterable} from '@jsepia/utils'

isIterable()       // true
isIterable([])     // true
isIterable('meow') // true

isIterable(null)   // false
isIterable({})     // false

isNumeric

Determines if a value is numeric. All numbers are considered numeric. Strings are numeric only if they begin with a number (e.g. 5px).

Another way of looking at it is: isNumeric(foo) === true implies parseInt(foo) will return a valid number.

import {isNumeric} from '@jsepia/utils'

isNumeric(-95) // true
isNumeric('5.6') // true
isNumeric('-5.6') // true
isNumeric('5px') // true

isNumeric('five') // false
isNumeric('E79') // false

isNumeric() // false
isNumeric(null) // false
isNumeric(true) // false
isNumeric({}) // false
isNumeric([]) // false

isObject

Returns true if a value has the type object and is not null. This function helps you determine if it's safe to query a value's properties or perform any other object-specific operations on it.

import {isObject} from '@jsepia/utils'

isObject()              // false
isObject(null)          // false (even though typeof null === 'object')
isObject(function() {}) // false

isObject({})         // true
isObject([])         // true

// gotchas
isObject(true)          // false
isObject(new Boolean()) // false
isObject(1)             // false
isObject(new Number())  // false
isObject('')            // false
isObject(new String())  // false

isPlainObject

Determines whether a value is a plain object - i.e. an object that is not an instance of a prototype or class, or otherwise does not have a constructor

import {isPlainObject} from '@jsepia/utils'

isPlainObject()            // false
isPlainObject([])          // false (even though typeof [] === 'object')
isPlainObject(NaN)         // false (even though NaN is a Number type)
isPlainObject(new Date())  // false

isPlainObject({})         // true

URL/URI manipulation

buildUri

import {buildUri} from '@jsepia/utils'

buildUri({
  // it supports the basic options you would expect
  protocol: 'http',
  host: 'juliosepia.com',
  port: '8080',
  path: '/posts/util.html',
  anchor: 'introduction', // hash

  // you can pass credentials separately
  user: 'jsepia',
  password: 'hunter2',

  // or as a single string
  userInfo: 'jsepia:hunter2',

  // you can pass query params separately
  queryKey: {
    version: '1.0',
    format: 'html'
  },

  // or as a single string
  query: 'version=1.0&format=html',
})

Output:

http://jsepia:hunter2@juliosepia.com:8080/posts/util.html?version=1.0&format=html#introduction

parseUri

Original by Steven Levithan

parseUri('http://jsepia:hunter2@juliosepia.com/posts/util.html?version=1.0&format=html#introduction')

Output:

{
  "anchor": "introduction",
  "authority": "jsepia:hunter2@juliosepia.com",
  "directory": "/posts/",
  "file": "util.html",
  "host": "juliosepia.com",
  "password": "hunter2",
  "path": "/posts/util.html",
  "port": "",
  "protocol": "http",
  "query": "version=1.0&format=html",
  "queryKey": {
    "format": "html",
    "version": "1.0",
  },
  "relative": "/posts/util.html?version=1.0&format=html#introduction",
  "source": "http://jsepia:hunter2@juliosepia.com/posts/util.html?version=1.0&format=html#introduction",
  "user": "jsepia",
  "userInfo": "jsepia:hunter2"
}

Validation

isValidUrl

import {isValidUrl} from '@jsepia/utils'

const url = prompt('enter URL here')
if (isValidUrl(url)) {
  request(url).then(
    (response) => handleResponse,
    (err) => handleError
  )
}
else {
  handleError(new Error(`Invalid URL: ${url}`))
}

TODO

  • Test the exported library
  • Split into bundles

Testing

# unit test
yarn test

# integ test (for CI and stuff)
yarn build && yarn test:integ

Readme

Keywords

none

Package Sidebar

Install

npm i @jsepia/utils

Weekly Downloads

1

Version

1.5.2

License

Apache-2.0

Last publish

Collaborators

  • jsepia