Skip to content

Commit 749cec0

Browse files
committed
Add json-prune-fetch-response scriptlet
As per request from filter list maintainers. Usage: ...##+js(json-prune-fetch-response, prune paths [, needle paths [, ...varargs ]]) See `json-prune` scriptlet for usage. Possible variable arguments: ..., log, [match | nomatch | all] ..., propsToMatch, [see prevent-xhr]
1 parent f8a83ff commit 749cec0

File tree

1 file changed

+91
-37
lines changed

1 file changed

+91
-37
lines changed

assets/resources/scriptlets.js

Lines changed: 91 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1213,54 +1213,108 @@ function jsonPrune(
12131213
const safe = safeSelf();
12141214
const stackNeedleDetails = safe.initPattern(stackNeedle, { canNegate: true });
12151215
const extraArgs = safe.getExtraArgs(Array.from(arguments), 3);
1216-
const logLevel = shouldLog(extraArgs);
1217-
const fetchPropNeedles = parsePropertiesToMatch(extraArgs.fetchPropsToMatch, 'url');
1218-
if (
1219-
fetchPropNeedles.size === 0 ||
1220-
matchObjectProperties(fetchPropNeedles, { url: 'undefined' })
1221-
) {
1222-
JSON.parse = new Proxy(JSON.parse, {
1223-
apply: function(target, thisArg, args) {
1224-
const objBefore = Reflect.apply(target, thisArg, args);
1225-
const objAfter = objectPrune(
1226-
objBefore,
1227-
rawPrunePaths,
1228-
rawNeedlePaths,
1229-
stackNeedleDetails,
1230-
extraArgs
1231-
);
1232-
return objAfter || objBefore;
1233-
},
1234-
});
1235-
}
1236-
Response.prototype.json = new Proxy(Response.prototype.json, {
1216+
JSON.parse = new Proxy(JSON.parse, {
12371217
apply: function(target, thisArg, args) {
1238-
const dataPromise = Reflect.apply(target, thisArg, args);
1239-
let outcome = 'match';
1240-
if ( fetchPropNeedles.size !== 0 ) {
1241-
if ( matchObjectProperties(fetchPropNeedles, thisArg) === false ) {
1242-
outcome = 'nomatch';
1243-
}
1218+
const objBefore = Reflect.apply(target, thisArg, args);
1219+
const objAfter = objectPrune(
1220+
objBefore,
1221+
rawPrunePaths,
1222+
rawNeedlePaths,
1223+
stackNeedleDetails,
1224+
extraArgs
1225+
);
1226+
return objAfter || objBefore;
1227+
},
1228+
});
1229+
}
1230+
1231+
/*******************************************************************************
1232+
*
1233+
* json-prune-fetch-response.js
1234+
*
1235+
* Prune JSON response of fetch requests.
1236+
*
1237+
**/
1238+
1239+
builtinScriptlets.push({
1240+
name: 'json-prune-fetch-response.js',
1241+
fn: jsonPruneFetchResponse,
1242+
dependencies: [
1243+
'match-object-properties.fn',
1244+
'object-prune.fn',
1245+
'parse-properties-to-match.fn',
1246+
'safe-self.fn',
1247+
'should-log.fn',
1248+
],
1249+
});
1250+
function jsonPruneFetchResponse(
1251+
rawPrunePaths = '',
1252+
rawNeedlePaths = ''
1253+
) {
1254+
const safe = safeSelf();
1255+
const extraArgs = safe.getExtraArgs(Array.from(arguments), 2);
1256+
const logLevel = shouldLog({ log: rawPrunePaths === '' || extraArgs.log, });
1257+
const log = logLevel ? ((...args) => { safe.uboLog(...args); }) : (( ) => { });
1258+
const propNeedles = parsePropertiesToMatch(extraArgs.propsToMatch, 'url');
1259+
const applyHandler = function(target, thisArg, args) {
1260+
const fetchPromise = Reflect.apply(target, thisArg, args);
1261+
if ( logLevel === true ) {
1262+
log('json-prune-fetch-response:', JSON.stringify(Array.from(args)).slice(1,-1));
1263+
}
1264+
if ( rawNeedlePaths === '' ) { return fetchPromise; }
1265+
let outcome = 'match';
1266+
if ( propNeedles.size !== 0 ) {
1267+
const objs = [ args[0] instanceof Object ? args[0] : { url: args[0] } ];
1268+
if ( args[1] instanceof Object ) {
1269+
objs.push(args[1]);
1270+
}
1271+
if ( matchObjectProperties(propNeedles, ...objs) === false ) {
1272+
outcome = 'nomatch';
12441273
}
12451274
if ( outcome === logLevel || logLevel === 'all' ) {
1246-
safe.uboLog(
1247-
`json-prune / Response.json() (${outcome})`,
1248-
`\n\tfetchPropsToMatch: ${JSON.stringify(Array.from(fetchPropNeedles)).slice(1,-1)}`,
1249-
'\n\tprops:', thisArg,
1275+
log(
1276+
`json-prune-fetch-response (${outcome})`,
1277+
`\n\tfetchPropsToMatch: ${JSON.stringify(Array.from(propNeedles)).slice(1,-1)}`,
1278+
'\n\tprops:', ...args,
12501279
);
12511280
}
1252-
if ( outcome === 'nomatch' ) { return dataPromise; }
1253-
return dataPromise.then(objBefore => {
1281+
}
1282+
if ( outcome === 'nomatch' ) { return fetchPromise; }
1283+
return fetchPromise.then(responseBefore => {
1284+
const response = responseBefore.clone();
1285+
return response.json().then(objBefore => {
1286+
if ( typeof objBefore !== 'object' ) { return responseBefore; }
12541287
const objAfter = objectPrune(
12551288
objBefore,
12561289
rawPrunePaths,
12571290
rawNeedlePaths,
1258-
stackNeedleDetails,
1291+
{ matchAll: true },
12591292
extraArgs
1260-
);
1261-
return objAfter || objBefore;
1293+
);
1294+
if ( typeof objAfter !== 'object' ) { return responseBefore; }
1295+
const responseAfter = Response.json(objAfter, {
1296+
status: responseBefore.status,
1297+
statusText: responseBefore.statusText,
1298+
headers: responseBefore.headers,
1299+
});
1300+
Object.defineProperties(responseAfter, {
1301+
ok: { value: responseBefore.ok },
1302+
redirected: { value: responseBefore.redirected },
1303+
type: { value: responseBefore.type },
1304+
url: { value: responseBefore.url },
1305+
});
1306+
return responseAfter;
1307+
}).catch(reason => {
1308+
log('json-prune-fetch-response:', reason);
1309+
return responseBefore;
12621310
});
1263-
},
1311+
}).catch(reason => {
1312+
log('json-prune-fetch-response:', reason);
1313+
return fetchPromise;
1314+
});
1315+
};
1316+
self.fetch = new Proxy(self.fetch, {
1317+
apply: applyHandler
12641318
});
12651319
}
12661320

0 commit comments

Comments
 (0)