0.1.1
added pathToString helper. Wrote helper tests for pathToString, getKeys, and walkPathmaster
parent
958e46afd9
commit
1681f56326
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@uci-utils/obj-nested-prop",
|
"name": "@uci-utils/obj-nested-prop",
|
||||||
"version": "0.1.0",
|
"version": "0.1.1",
|
||||||
"description": "Functions to get set, delete, and search nested properties of an object",
|
"description": "Functions to get set, delete, and search nested properties of an object",
|
||||||
"main": "src/obj-nested-prop.js",
|
"main": "src/obj-nested-prop.js",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import { check } from '@uci-utils/type'
|
import { check } from '@uci-utils/type'
|
||||||
import { logger } from '@uci-utils/logger'
|
import { logger } from '@uci-utils/logger'
|
||||||
|
|
||||||
const log = logger({ file: '/src/obj-prop.js', package: '@uci-utils/obj-prop' })
|
const log = logger({ file: '/src/obj-nested-prop.js', package: '@uci-utils/obj-nested-prop' })
|
||||||
|
|
||||||
const set = (obj, path, value, opts = {}) => {
|
function set (obj, path, value, opts = {}) {
|
||||||
if (value === undefined) return del(obj, path)
|
if (value === undefined) return del(obj, path)
|
||||||
const keys = validateArgs(obj, path, opts)
|
const keys = validateArgs(obj, path, opts)
|
||||||
if (!keys) return obj
|
if (!keys) return obj
|
||||||
|
@ -65,7 +65,7 @@ function get (obj, path) {
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
const getKeys = (path, opts = {}) => {
|
function getKeys (path, opts = {}) {
|
||||||
if (!(check.isString(path) || check.isArray(path) || check.isSymbol(path))) {
|
if (!(check.isString(path) || check.isArray(path) || check.isSymbol(path))) {
|
||||||
log.warn({ function: 'getKeys', path: path, msg: 'path was not valid' })
|
log.warn({ function: 'getKeys', path: path, msg: 'path was not valid' })
|
||||||
return false
|
return false
|
||||||
|
@ -98,12 +98,13 @@ const getKeys = (path, opts = {}) => {
|
||||||
return keys
|
return keys
|
||||||
}
|
}
|
||||||
|
|
||||||
function validateArgs (obj, path, opts) {
|
function pathToString (path, opts = {}) {
|
||||||
if (!check.isObject(obj)) {
|
const keys = getKeys(path, opts)
|
||||||
log.warn({ function: 'del', obj: obj, msg: 'passed is not an object' })
|
if (keys.reduce((res, key) => res && !check.isSymbol(key), true)) return keys.join(opts.dot || '.')
|
||||||
return false
|
else {
|
||||||
|
log.warn({ function: 'pathToString', path: path, keys: keys, opts: opts, msg: 'unable to make string of path' })
|
||||||
|
return null
|
||||||
}
|
}
|
||||||
return getKeys(path, opts)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function walkPath (obj, keys) {
|
function walkPath (obj, keys) {
|
||||||
|
@ -117,6 +118,7 @@ function walkPath (obj, keys) {
|
||||||
last = last[keys[i]]
|
last = last[keys[i]]
|
||||||
if (!last) {
|
if (!last) {
|
||||||
log.warn({ function: 'walkPath', obj: obj, keys: keys, key: keys[i], msg: 'key is not in object, aborting walk' })
|
log.warn({ function: 'walkPath', obj: obj, keys: keys, key: keys[i], msg: 'key is not in object, aborting walk' })
|
||||||
|
// will return undefined
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
log.trace({ function: 'walkPath', curProp: last, msg: 'fetching... deep property' })
|
log.trace({ function: 'walkPath', curProp: last, msg: 'fetching... deep property' })
|
||||||
|
@ -124,6 +126,16 @@ function walkPath (obj, keys) {
|
||||||
return last
|
return last
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// non exported local functions
|
||||||
|
|
||||||
|
const validateArgs = (obj, path, opts) => {
|
||||||
|
if (!check.isObject(obj)) {
|
||||||
|
log.warn({ function: 'del', obj: obj, msg: 'passed is not an object' })
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return getKeys(path, opts)
|
||||||
|
}
|
||||||
|
|
||||||
const isNumber = value => {
|
const isNumber = value => {
|
||||||
if (value.trim() !== '') {
|
if (value.trim() !== '') {
|
||||||
const number = Number(value)
|
const number = Number(value)
|
||||||
|
@ -144,4 +156,4 @@ const isValidKey = key => {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
export { set, get, del, getKeys, walkPath }
|
export { set, get, del, getKeys, walkPath, pathToString }
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import assert from 'assert'
|
import assert from 'assert'
|
||||||
import { get, set, del } from '../src/obj-nested-prop.js'
|
import { get, set, del, getKeys, walkPath, pathToString } from '../src/obj-nested-prop.js'
|
||||||
import { check } from '@uci-utils/type'
|
import { check } from '@uci-utils/type'
|
||||||
|
|
||||||
const date = new Date(Date.now())
|
const date = new Date(Date.now())
|
||||||
|
@ -291,3 +291,40 @@ describe('options.split', () => {
|
||||||
assert.strictEqual(o.a['b.c.d'].e, 'c')
|
assert.strictEqual(o.a['b.c.d'].e, 'c')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('helpers', () => {
|
||||||
|
it('getKeys: will split path as string or array into array of single keys', () => {
|
||||||
|
const test = 'atest'
|
||||||
|
const key = Symbol('akey')
|
||||||
|
assert.deepStrictEqual(getKeys('this.is\\.a.string'), ['this', 'is.a', 'string'])
|
||||||
|
assert.deepStrictEqual(getKeys(['this.is.a.string', key, test]),
|
||||||
|
['this', 'is', 'a', 'string', key, 'atest'])
|
||||||
|
})
|
||||||
|
|
||||||
|
it('pathToString: converts path with getKeys and returns joined string', () => {
|
||||||
|
const p1 = ['this', 'is%an', 'array']
|
||||||
|
const p2 = [['this', 'is%an', 'array'], { dot: '#', delimiter: '.%' }]
|
||||||
|
// console.log(pathToString(p1))
|
||||||
|
// console.log(pathToString(...p2))
|
||||||
|
assert.deepStrictEqual(pathToString(p1), 'this.is%an.array')
|
||||||
|
assert.deepStrictEqual(pathToString(...p2), 'this#is#an#array')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('pathToString: returns null if unable to make string (e.g. path contains Symbol)', () => {
|
||||||
|
const p1 = [['this', Symbol('test'), 'array'], { dot: '#', delimiter: '.%' }]
|
||||||
|
// console.log('has symbol', pathToString(...p1))
|
||||||
|
assert.strictEqual(pathToString(...p1), null)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('walkPath: will walk an array of keys deep into object', () => {
|
||||||
|
const path = 'this.is.a.value'
|
||||||
|
const path2 = 'this.is.a.bogus.value'
|
||||||
|
const path3 = 'this.is.object'
|
||||||
|
const o = {}
|
||||||
|
set(o, path, 'some value')
|
||||||
|
set(o, path3, { a: 'what', b: 'when' })
|
||||||
|
assert.strictEqual(walkPath(o, getKeys(path)), 'some value')
|
||||||
|
assert.strictEqual(walkPath(o, getKeys(path2)), undefined)
|
||||||
|
assert.deepStrictEqual(walkPath(o, getKeys(path3)), { a: 'what', b: 'when' })
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
Loading…
Reference in New Issue