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
1 changed files with 24 additions and 12 deletions

View File

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