json-magic
Advanced tools
Comparing version 0.0.12 to 0.1.0
@@ -1,1 +0,1 @@ | ||
module.exports=require('./lib/Magic'); | ||
module.exports = require('./lib/Magic'); |
424
lib/Magic.js
@@ -1,37 +0,29 @@ | ||
const $check=require('check-types'); | ||
const jsonPointer=require('./JSONPointer.js'); | ||
const $check = require('check-types'); | ||
const jsonPointer = require('json-pointer'); | ||
class Magic{ | ||
constructor(){} | ||
class Magic { | ||
constructor() {} | ||
/**Parse a string path to an array | ||
* | ||
* @param {string} path - the path to parse | ||
* @param {string} [separator] - the separator to use. Either . or / or dot | ||
* @returns {null|*[]|string[]|*} | ||
*/ | ||
static parsePath(path,separator){ | ||
if (!path)return null; | ||
if ($check.array(path))return path; | ||
if (!$check.string(path))throw new Error('Invalid type for path'); | ||
static parsePath(path, separator) { | ||
if (!path) return null; | ||
if ($check.array(path)) return path; | ||
if (!$check.string(path)) throw new Error('Invalid type for path'); | ||
let sep="/"; | ||
if (separator){ | ||
sep=separator; | ||
}else if (separator==="dot"){ | ||
sep="."; | ||
}else{ | ||
if (count(path,'.')>count(path,'/')){ | ||
sep="."; | ||
}else{ | ||
sep="/"; | ||
let sep = '/'; | ||
if (separator) { | ||
sep = separator; | ||
} else { | ||
if (count(path, '.') > count(path, '/')) { | ||
sep = '.'; | ||
} else { | ||
sep = '/'; | ||
} | ||
} | ||
if (path.indexOf(sep)>-1){ | ||
if (path.indexOf(sep)===0){ | ||
path=path.substring(sep.length); | ||
if (path.indexOf(sep) > -1) { | ||
if (path.indexOf(sep) === 0) { | ||
path = path.substring(sep.length); | ||
} | ||
return path.split(sep); | ||
}else{ | ||
} else { | ||
return [path]; | ||
@@ -41,39 +33,24 @@ } | ||
static compilePath(path, seprator, ignoreLeading) { | ||
if (!path) return path; | ||
if (!$check.array(path)) throw new Error('Invalid type for path'); | ||
const sep = seprator || '/'; | ||
/**Compiles an array to a path | ||
* | ||
* @param {array} path - the path to compile | ||
* @param {string} [separator] - the separator to use | ||
* @param {boolean} [ignoreLeading] - ignore the leading separator unless dot notation | ||
* @returns {string|*} | ||
*/ | ||
static compilePath(path,separator,ignoreLeading){ | ||
if (!path)return path; | ||
if (!$check.array(path))throw new Error('Invalid type for path'); | ||
let sep=separator||"/"; | ||
if (sep==='.'||sep==="dot"){ | ||
if (sep === '.') { | ||
return path.join('.'); | ||
}else{ | ||
return (ignoreLeading?"":sep) + path.join(sep); | ||
} else { | ||
return (ignoreLeading ? '' : sep) + path.join(sep); | ||
} | ||
} | ||
/**Check if the path is in the object | ||
* | ||
* @param {object||array} obj - The object to check | ||
* @param {string|array} path - The path to check | ||
* @returns {boolean} | ||
*/ | ||
static has(obj,path){ | ||
if (!obj)return false; | ||
let pathArr=Magic.parsePath(path); | ||
let curObj=obj; | ||
static has(obj, path) { | ||
if (!obj) return false; | ||
const pathArr = Magic.parsePath(path); | ||
let curObj = obj; | ||
for (let attr of pathArr){ | ||
if (!curObj[attr]){ | ||
for (const attr of pathArr) { | ||
if (!curObj[attr]) { | ||
return false; | ||
}else{ | ||
curObj=curObj[attr]; | ||
} else { | ||
curObj = curObj[attr]; | ||
} | ||
@@ -87,84 +64,58 @@ } | ||
* | ||
* @param {object|array} obj - the object to check | ||
* @param {string|array} path - the path to retreive | ||
* @param {string} [separator] - the path separator, either slash or dot | ||
* @returns {*} | ||
* @param {Object} object | ||
* @param {String|Array} path | ||
* @param {String} separator | ||
* @return {*} | ||
*/ | ||
static get (obj,path,separator){ | ||
if (!obj)throw new Error('Invalid object for get'); | ||
if (!$check.object(obj)&&!$check.array(obj))throw new Error('Invalid object for get'); | ||
return jsonPointer.get(obj,Magic.parsePath(path,separator)); | ||
static get(object, path, separator) { | ||
if (!object) throw new Error('Invalid object for get'); | ||
if (!$check.object(object) && !$check.array(object)) throw new Error('Invalid object for get'); | ||
return jsonPointer.get(object, Magic.parsePath(path, separator)); | ||
} | ||
/**Set a value for the path on the specified object | ||
* | ||
* @param {object|array} obj - the object to set the value on | ||
* @param {string|array} path - the path to set the value on | ||
* @param {*} value - the value to set | ||
* @returns {*} | ||
*/ | ||
static set(obj,path,value){ | ||
if (!obj)throw new Error('Invalid object for set'); | ||
if (!$check.object(obj)&&!$check.array(obj))throw new Error('Invalid object for set'); | ||
return jsonPointer.set(obj,Magic.parsePath(path),value); | ||
static set(object, path, value) { | ||
if (!object) throw new Error('Invalid object for set'); | ||
if (!$check.object(object) && !$check.array(object)) throw new Error('Invalid object for set'); | ||
return jsonPointer.set(object, Magic.parsePath(path), value); | ||
} | ||
/**Removes the value at the specified path | ||
* | ||
* @param {object|array} obj - the object to set the value on | ||
* @param {string|array} path - the path to set the value on | ||
* @returns {*} | ||
*/ | ||
static remove(obj,path){ | ||
if (!obj)throw new Error('Invalid object for remove'); | ||
if (!$check.object(obj)&&!$check.array(obj))throw new Error('Invalid object for remove'); | ||
return jsonPointer.remove(obj,Magic.parsePath(path)); | ||
static remove(object, path) { | ||
if (!object) throw new Error('Invalid object for remove'); | ||
if (!$check.object(object) && !$check.array(object)) throw new Error('Invalid object for remove'); | ||
return jsonPointer.remove(object, Magic.parsePath(path)); | ||
} | ||
/**Returns a dictionary of paths generated from the object | ||
* | ||
* @param {object|array} obj - The object to generate a set of paths from | ||
* @param {string} [separator] - The separator to show on the paths | ||
* @returns {{}} | ||
*/ | ||
static pathDict(obj,separator){ | ||
if (separator&&separator.toLowerCase()!=='/'){ | ||
let dict=jsonPointer.dict(obj); | ||
let newDict={}; | ||
for (let k in dict){ | ||
if (!dict.hasOwnProperty(k))continue; | ||
let newK=k.split('/'); | ||
static pathDict(object, separator) { | ||
if (separator && separator.toLowerCase() !== '/') { | ||
const dict = jsonPointer.dict(object); | ||
const newDict = {}; | ||
for (const k in dict) { | ||
if (!dict.hasOwnProperty(k)) continue; | ||
const newK = k.split('/'); | ||
newK.shift(); | ||
newDict[newK.join('.')]=dict[k]; | ||
newDict[newK.join('.')] = dict[k]; | ||
} | ||
return newDict; | ||
}else{ | ||
return jsonPointer.dict(obj); | ||
} else { | ||
return jsonPointer.dict(object); | ||
} | ||
} | ||
/**Returns an array of paths defined in the object | ||
* | ||
* @param {object|array} obj - | ||
* @param {string} [format] - the format for the path, e.g. . or / | ||
* @returns {[]} | ||
*/ | ||
static pathArray(obj,format){ | ||
let dict=jsonPointer.dict(obj); | ||
let newDict=[]; | ||
static pathArray(object, format) { | ||
const dict = jsonPointer.dict(object); | ||
const newDict = []; | ||
for (let k in dict){ | ||
if (!dict.hasOwnProperty(k))continue; | ||
if (format&&(format.toLowerCase()==='dot'||format===".")){ | ||
let newK=k.split('/'); | ||
for (const k in dict) { | ||
if (!dict.hasOwnProperty(k)) continue; | ||
if (format && format.toLowerCase() === 'dot') { | ||
const newK = k.split('/'); | ||
newK.shift(); | ||
newDict.push({ | ||
path:newK.join('.'), | ||
value:dict[k] | ||
path: newK.join('.'), | ||
value: dict[k], | ||
}); | ||
}else{ | ||
} else { | ||
newDict.push({ | ||
path:k, | ||
value:dict[k] | ||
path: k, | ||
value: dict[k], | ||
}); | ||
@@ -177,27 +128,20 @@ } | ||
/**Walk an object or array and call an iterator function | ||
* | ||
* @param {object|array} obj - The object or array to walk | ||
* @param {function} iterator - the iterator | ||
* @param {string} [separator] - the path separator | ||
* @returns {void|*} | ||
*/ | ||
static walk(obj,iterator,separator) { | ||
if (!obj) return obj; | ||
let sep = separator || "/"; | ||
static walk(object, iterator, separator) { | ||
if (!object) return object; | ||
const sep = separator || '/'; | ||
//if not an object or array, then base path | ||
if (!$check.object(obj) && !$check.array(obj)) { | ||
// if not an object or array, then base path | ||
if (!$check.object(object) && !$check.array(object)) { | ||
if (sep === '.') { | ||
return iterator(obj, ''); | ||
return iterator(object, ''); | ||
} else { | ||
return iterator(obj, sep); | ||
return iterator(object, sep); | ||
} | ||
} | ||
return jsonPointer.walk(obj, (value, path)=> { | ||
return jsonPointer.walk(object, (value, path) => { | ||
let newPath = path; | ||
if (sep !== "/") { | ||
newPath = Magic.compilePath(Magic.parsePath(path, "/"), separator); | ||
if (sep !== '/') { | ||
newPath = Magic.compilePath(Magic.parsePath(path, '/'), separator); | ||
} | ||
@@ -208,29 +152,22 @@ return iterator(value, newPath); | ||
/**Renames a key by the renamer function | ||
* | ||
* @param {object|array} obj - object to rename key on | ||
* @param {function} renamer - the function to call for each key | ||
* @param {string} [separator] - the path separator | ||
* @returns {*} | ||
*/ | ||
static renameKey(obj,renamer,separator){ | ||
if (!obj)return obj; | ||
let sep=separator||"/"; | ||
if (!renamer)return object; | ||
static renameKey(object, renamer, separator) { | ||
if (!object) return object; | ||
const sep = separator || '/'; | ||
if (!renamer) return object; | ||
//if not an object or array, then base path | ||
if (!$check.object(obj)&&!$check.array(obj)){ | ||
return obj; | ||
// if not an object or array, then base path | ||
if (!$check.object(object) && !$check.array(object)) { | ||
return object; | ||
} | ||
let renamePaths=[]; | ||
const renamePaths = []; | ||
const inner=(curObj,curPath,curKey)=>{ | ||
if ($check.assigned(curKey)){ | ||
let newKey=renamer(curKey,Magic.compilePath(curPath,sep)); | ||
if (newKey&&newKey!==curKey){ | ||
const inner = (curObj, curPath, curKey) => { | ||
if ($check.assigned(curKey)) { | ||
const newKey = renamer(curKey, Magic.compilePath(curPath, sep)); | ||
if (newKey && newKey !== curKey) { | ||
renamePaths.push({ | ||
curPath:curPath, | ||
newKey:newKey, | ||
newPath:curPath.slice(0,curPath.length-1).concat([newKey]) | ||
curPath: curPath, | ||
newKey: newKey, | ||
newPath: curPath.slice(0, curPath.length - 1).concat([newKey]), | ||
}); | ||
@@ -240,10 +177,10 @@ } | ||
if ($check.array(curObj)){ | ||
for (let i=0;i<curObj.length;i++) { | ||
if ($check.array(curObj)) { | ||
for (let i = 0; i < curObj.length; i++) { | ||
inner(curObj[i], curPath.concat(i), i); | ||
} | ||
}else if ($check.object(curObj)){ | ||
for (let k in curObj){ | ||
} else if ($check.object(curObj)) { | ||
for (const k in curObj) { | ||
if (!curObj.hasOwnProperty(k)) continue; | ||
inner(curObj[k],curPath.concat(k),k); | ||
inner(curObj[k], curPath.concat(k), k); | ||
} | ||
@@ -253,84 +190,71 @@ } | ||
inner(obj,[],null); | ||
inner(object, [], null); | ||
for (let renamePath of renamePaths){ | ||
Magic.set(obj,renamePath.newPath, Magic.get(obj,renamePath.curPath)); | ||
for (const renamePath of renamePaths) { | ||
Magic.set(object, renamePath.newPath, Magic.get(object, renamePath.curPath)); | ||
} | ||
let removePaths=renamePaths.sort((a,b)=>{ | ||
if (a.curPath.length>b.curPath.length)return -1; | ||
if (a.curPath.length<b.curPath.length)return 1; | ||
return 0; | ||
const removePaths = renamePaths.sort((a, b) => { | ||
if (a.curPath.length > b.curPath.length) return -1; | ||
if (a.curPath.length < b.curPath.length) return 1; | ||
return 0; | ||
}); | ||
for (let removePath of removePaths){ | ||
Magic.remove(obj,removePath.curPath); | ||
for (const removePath of removePaths) { | ||
Magic.remove(object, removePath.curPath); | ||
} | ||
return obj; | ||
return object; | ||
} | ||
/**Changes a value in an object passing each value to the changer function | ||
* | ||
* @param {object|array} obj - object to rename key on | ||
* @param {function} changer - the function to call for each key | ||
* @param {string} [separator] - the path separator | ||
* @returns {*} | ||
*/ | ||
static changeValue(obj,changer,separator){ | ||
if (!obj)return obj; | ||
let sep=separator||"/"; | ||
if (!changer)return obj; | ||
static changeValue(object, changer, separator) { | ||
if (!object) return object; | ||
const sep = separator || '/'; | ||
if (!changer) return object; | ||
//if not an object or array, then base path | ||
if (!$check.object(obj)&&!$check.array(obj)){ | ||
return obj; | ||
// if not an object or array, then base path | ||
if (!$check.object(object) && !$check.array(object)) { | ||
return object; | ||
} | ||
let setPaths=[]; | ||
const setPaths = []; | ||
Magic.walk(obj,(val,path)=>{ | ||
let newVal=changer(val,path); | ||
if (newVal!==val){ | ||
setPaths.push({ | ||
path:path, | ||
newVal:newVal | ||
}); | ||
} | ||
},sep); | ||
Magic.walk( | ||
object, | ||
(val, path) => { | ||
const newVal = changer(val, path); | ||
if (newVal !== val) { | ||
setPaths.push({ | ||
path: path, | ||
newVal: newVal, | ||
}); | ||
} | ||
}, | ||
sep | ||
); | ||
for (let setPath of setPaths){ | ||
Magic.set(obj,setPath.path, setPath.newVal); | ||
for (const setPath of setPaths) { | ||
Magic.set(object, setPath.path, setPath.newVal); | ||
} | ||
return obj; | ||
return object; | ||
} | ||
/**Converts all dates to ISOStrings | ||
* | ||
* @param {object|array} obj - object to rename key on | ||
* @returns {*} | ||
*/ | ||
static convertDateTOISOString(obj){ | ||
Magic.walk(obj,function(value,path){ | ||
if ($check.date(value)){ | ||
Magic.set(obj,path,value.toISOString()); | ||
static convertDateTOISOString(object) { | ||
Magic.walk(object, function (value, path) { | ||
if ($check.date(value)) { | ||
Magic.set(object, path, value.toISOString()); | ||
} | ||
}); | ||
return obj; | ||
return object; | ||
} | ||
/**Fixes an object or array to remove any fields starting with $ that can cause issues storing in mongo | ||
* | ||
* @param {array|object} obj - the object to convert | ||
* @returns {*} | ||
*/ | ||
static fixForMongo(obj){ | ||
return Magic.renameKey(obj,(key,path)=>{ | ||
if (!key)return key; | ||
if (!$check.string(key))return key; | ||
if (key.startsWith('$')){ | ||
key='_' + key.substring(1); | ||
static fixForMongo(object) { | ||
return Magic.renameKey(object, (key, path) => { | ||
if (!key) return key; | ||
if (!$check.string(key)) return key; | ||
if (key.startsWith('$')) { | ||
key = '_' + key.substring(1); | ||
} | ||
key=key.replace(/\./g,'_'); | ||
key = key.replace(/\./g, '_'); | ||
@@ -340,48 +264,2 @@ return key; | ||
} | ||
/**Sets a property and value on each object and subObject | ||
* | ||
* @param {array|object} obj - the object to convert | ||
* @param {string} property - the property name to set | ||
* @param {boolean} override - override the value | ||
* @param {*} value - the value to set | ||
*/ | ||
static setProperty(obj,property,value,override){ | ||
if (!obj)return obj; | ||
//if not an object or array, then base path | ||
if (!$check.object(obj)&&!$check.array(obj)){ | ||
return obj; | ||
} | ||
let setPaths=[]; | ||
const inner=(curObj,curPath,curKey)=>{ | ||
if ($check.array(curObj)){ | ||
for (let i=0;i<curObj.length;i++) { | ||
inner(curObj[i], curPath.concat(i), i); | ||
} | ||
}else if ($check.object(curObj)){ | ||
if(!curObj[property]||override){ | ||
setPaths.push({ | ||
path:curPath.concat(property) | ||
}); | ||
} | ||
for (let k in curObj){ | ||
if (!curObj.hasOwnProperty(k)) continue; | ||
inner(curObj[k],curPath.concat(k),k); | ||
} | ||
} | ||
}; | ||
inner(obj,[],null); | ||
for (let setPath of setPaths){ | ||
Magic.set(obj,setPath.path, value); | ||
} | ||
return obj; | ||
} | ||
} | ||
@@ -394,3 +272,2 @@ | ||
function count(str, substr) { | ||
@@ -405,3 +282,2 @@ str = makeString(str); | ||
module.exports=Magic; | ||
module.exports = Magic; |
{ | ||
"name": "json-magic", | ||
"version": "0.0.12", | ||
"version": "0.1.0", | ||
"description": "Utilities for manipulating JSON objects.", | ||
"homepage": "https://github.com/filepounder/json-magic", | ||
"main": "index.js", | ||
"files": [ | ||
"lib/", | ||
"index.js" | ||
], | ||
"scripts": { | ||
"lint": "eslint .", | ||
"prettier": "prettier . --write", | ||
"test": "mocha --reporter spec --bail --check-leaks test/", | ||
"test-ci": "nyc --reporter text-summary mocha -- --reporter spec --check-leaks test/", | ||
"test-cov": "nyc --reporter lcov --reporter text mocha -- --reporter dot --check-leaks test/" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/filepounder/json-magic.git" | ||
"url": "https://github.com/synatic/json-magic.git" | ||
}, | ||
"keywords": [ | ||
"json" | ||
], | ||
"author": { | ||
"name": "Martin Naude", | ||
"email": "martin@filepounder.com" | ||
"name": "FilePounder Inc", | ||
"url": "https://synatic.com" | ||
}, | ||
"dependencies": { | ||
"check-types": "11.1.2" | ||
"contributors": [ | ||
{ | ||
"name": "Martin Naude" | ||
}, | ||
{ | ||
"name": "Thiren Bunsee" | ||
} | ||
], | ||
"license": "MIT", | ||
"bugs": { | ||
"url": "https://github.com/synatic/json-magic/issues" | ||
}, | ||
"homepage": "https://github.com/synatic/json-magic#readme", | ||
"engines": { | ||
"node": ">=6.0.0" | ||
"node": ">=12" | ||
}, | ||
"license": "MIT", | ||
"dependencies": { | ||
"check-types": "11.1.2", | ||
"json-pointer": "0.6.1" | ||
}, | ||
"devDependencies": { | ||
"mocha": "6.1.4" | ||
"eslint": "^7.16.0", | ||
"eslint-config-google": "^0.14.0", | ||
"eslint-config-prettier": "^7.1.0", | ||
"mocha": "^8.2.1", | ||
"nyc": "^15.1.0", | ||
"prettier": "^2.2.1" | ||
} | ||
} |
# Utilities for manipulating JSON Objects | ||
## Installation | ||
## Usage |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No bug tracker
MaintenancePackage does not have a linked bug tracker in package.json.
Found 1 instance in 1 package
0
10502
2
6
232
6
1
+ Addedjson-pointer@0.6.1
+ Addedforeach@2.0.6(transitive)
+ Addedjson-pointer@0.6.1(transitive)