Scriptlets icon indicating copy to clipboard operation
Scriptlets copied to clipboard

Improve 'json-prune' or implement new scriptlet

Open slavaleleka opened this issue 3 years ago • 18 comments

there are few issues:

1 current json-prune does not match values if we need specify pruning, only keys — obligatoryProps — are checked

2 if specific array item has to be pruned and we can target such items by their extra fields

#%#//scriptlet('json-prune', 'recs_group.[].tiles.[].[].*', 'recs_group.[].tiles.[].[].ad_origin')

but whole recs_group.[].tiles.[].[] array items will be pruned, not just ones with ad_origin. check on fontanka.ru https://uploads.adguard.com/slbdzdrv7cfxo.png

slavaleleka avatar Jan 24 '22 07:01 slavaleleka

@slavaleleka what do you think about implementing a scriptlet that supports jq-like syntax for that? At least a subset of it. https://stedolan.github.io/jq/tutorial/

Alternatively, there is this: https://jmespath.org/

I do not suggest supporting it fully, but we could take that syntax as a base and build our limited subset of it. This way it'd be easier for the scriptlet users to understand the capabilities.

PS: we'll probably need to reassign this task to a later milestone.

ameshkov avatar Jan 24 '22 10:01 ameshkov

ngorskikh avatar Jun 20 '22 10:06 ngorskikh

@ngorskikh the spec should've been posted here I think: https://github.com/AdguardTeam/CoreLibs/issues/1447

We'll also need a filter expression for checking whether the value contains the specified string: ?(key-contains <key> <value>)

ameshkov avatar Jun 20 '22 11:06 ameshkov

Currently, $jsonprune modifier can modify only response of a request. However, during maintaining List-KR filter, I often need its scriptlet version.

Example:

Gmarket.co.kr

URL: https://gmarket.co.kr/ Description: Extended CSS can hide the elements having AD label. However, their network requests cannot be blocked with the previous modifiers and URL rules (including a RegExp) Related Issue: https://github.com/List-KR/List-KR/issues/563 Targeted array items: $props.pageProps.serverData.topWideBannerSection.banners[?(@.isAd == true)]

piquark6046 avatar Dec 03 '22 20:12 piquark6046

Could you please explain what you're trying to do with that request?

Do you need to block a request that contains such a JSON path?

ameshkov avatar Dec 04 '22 17:12 ameshkov

https://github.com/AdguardTeam/Scriptlets/issues/183#issuecomment-1336472219 Oh, I forgot to add what i want. What i want is a feature removing a property with a JSON path from result of calling JSON.parse.

piquark6046 avatar Dec 04 '22 18:12 piquark6046

So you'd like a scriptlet alternative to $jsonprune?

ameshkov avatar Dec 04 '22 18:12 ameshkov

Yes.

piquark6046 avatar Dec 04 '22 18:12 piquark6046

Makes sense, $jsonprune syntax is more powerful and the end goal was indeed to provide a scriptlet version of it.

Moved it to Scriptlets v1.9 for now. @slavaleleka @stanislav-atr what do you think about it? To understand better what's required please check out this issue in CL: https://github.com/AdguardTeam/CoreLibs/issues/1447

ameshkov avatar Dec 04 '22 18:12 ameshkov

we shall return to the issue later

slavaleleka avatar Dec 05 '22 17:12 slavaleleka

Later is now, @slavaleleka :)

Alex-302 avatar Apr 11 '23 13:04 Alex-302

the same is needed in scriptlets as well: https://github.com/AdguardTeam/CoreLibs/issues/1717

UPD: jsonp cannot be handled by the json-prune scriptlet

slavaleleka avatar May 18 '23 09:05 slavaleleka

second issue in first issue post cannot be fixed in current syntax implementation — obligatoryProps is checked for the whole json and there is no way to check exact inner array item child (which is object) and conditionally prune it while other array items remains unchanged

slavaleleka avatar May 19 '23 15:05 slavaleleka

@slavaleleka not sure what you mean, aren't filter expressions supposed to solve this?

ameshkov avatar May 21 '23 09:05 ameshkov

I mean current syntax implementation, not jsonpath filter expression

slavaleleka avatar May 22 '23 09:05 slavaleleka

I couldn't figure out how we can handle JSONP requests, apart from one method. For example, let's say there's a JSONP callback like this:

...
<script>
    function handleResponse(data) {
        console.log(JSON.stringify(data));
    }
</script>
<script src="http://server.com/jsonp?callback=handleResponse"></script>
...

We can find the matching callback function from the page and proxify the call to it.

maximtop avatar Jul 11 '23 14:07 maximtop

Probably jsonp shouldn't be in scope of this issue since there's no clear solution.

ameshkov avatar Jul 12 '23 14:07 ameshkov

Please take a look for json-prune scriptlet version: https://github.com/gorhill/uBlock/commit/3152896d428c54c76cfd66c3da110bd4d6506cbc and https://github.com/gorhill/uBlock/commit/14d60ac5d3a1c5c2b9b8c062ea31e4ddcd13a98f.

piquark6046 avatar Sep 07 '23 08:09 piquark6046