Add support for wildcard/array in json-prune

Add support for specially-named properties:

`[]`, to iterate through all elements in an array, in
order to deal more graciously with cases where the
property to remove is an element in an array. An
actual case:

    +js(json-prune, playlist.movies.0.adserver playlist.movies.1.adserver ...)

Can be now converted to:

    +js(json-prune, playlist.movies.[].adserver)

`*`, to iterate through all own properties of an object,
in order to deal with random-named properties. For
example (not an actual case):

    +js(json-prune, playlist.*.adserver)

Where `adserver` would be a property member of an
object which is itself a property of `playlist`, but
which name is unknown or is variable.
This commit is contained in:
Raymond Hill 2020-06-26 10:03:48 -04:00
parent da6cdf977e
commit f433932d86
No known key found for this signature in database
GPG key ID: 25E1490B761470C2

View file

@ -278,27 +278,42 @@
}
reLogNeedle = new RegExp(needle);
}
const findOwner = function(root, path) {
const findOwner = function(root, path, prune = false) {
let owner = root;
let chain = path;
for (;;) {
if ( owner instanceof Object === false ) { return; }
if ( owner instanceof Object === false ) { return false; }
const pos = chain.indexOf('.');
if ( pos === -1 ) {
return owner.hasOwnProperty(chain)
? [ owner, chain ]
: undefined;
const found = owner.hasOwnProperty(chain);
if ( found === false ) { return false; }
if ( prune ) {
delete owner[chain];
}
return true;
}
const prop = chain.slice(0, pos);
if ( owner.hasOwnProperty(prop) === false ) { return; }
if (
prop === '[]' && Array.isArray(owner) ||
prop === '*' && owner instanceof Object
) {
const next = chain.slice(pos + 1);
let found = false;
for ( const item of owner.values() ) {
found = findOwner(item, next, prune) || found;
}
return found;
}
if ( owner.hasOwnProperty(prop) === false ) { return false; }
owner = owner[prop];
chain = chain.slice(pos + 1);
}
};
const mustProcess = function(root) {
for ( const needlePath of needlePaths ) {
const details = findOwner(root, needlePath);
if ( details === undefined ) { return false; }
if ( findOwner(root, needlePath) === false ) {
return false;
}
}
return true;
};
@ -314,10 +329,7 @@
}
if ( mustProcess(r) === false ) { return r; }
for ( const path of prunePaths ) {
const details = findOwner(r, path);
if ( details !== undefined ) {
delete details[0][details[1]];
}
findOwner(r, path, true);
}
return r;
},