Skip to content

Commit 0fdbfdb

Browse files
committed
Improve json-edit scriptlet
1 parent 31020ad commit 0fdbfdb

1 file changed

Lines changed: 53 additions & 7 deletions

File tree

src/js/resources/json-edit.js

Lines changed: 53 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ import { safeSelf } from './safe-self.js';
4040
function editOutboundObjectFn(
4141
trusted = false,
4242
propChain = '',
43-
jsonq = '',
43+
jsonq = ''
4444
) {
4545
if ( propChain === '' ) { return; }
4646
const safe = safeSelf();
@@ -127,6 +127,42 @@ registerScriptlet(trustedEditOutboundObject, {
127127
});
128128

129129
/******************************************************************************/
130+
131+
function jsonEditFn(trusted = false, jsonq = '', ...varargs) {
132+
const safe = safeSelf();
133+
const logPrefix = safe.makeLogPrefix(
134+
`${trusted ? 'trusted-' : ''}json-edit`,
135+
jsonq,
136+
...varargs
137+
);
138+
const jsonp = JSONPath.create(jsonq);
139+
if ( jsonp.valid === false || jsonp.value !== undefined && trusted !== true ) {
140+
return safe.uboLog(logPrefix, 'Bad JSONPath query');
141+
}
142+
const extraArgs = safe.parseVarargs(varargs);
143+
const pattern = extraArgs.matches && safe.initPattern(extraArgs.matches);
144+
proxyApplyFn('JSON.parse', function(context) {
145+
const json = context.callArgs[0];
146+
const obj = context.reflect();
147+
if ( pattern && safe.testPattern(pattern, json) === false ) { return obj; }
148+
const objAfter = jsonp.apply(obj);
149+
if ( objAfter === undefined ) { return obj; }
150+
safe.uboLog(logPrefix, 'Edited');
151+
if ( safe.logLevel > 1 ) {
152+
safe.uboLog(logPrefix, `After edit:\n${safe.JSON_stringify(objAfter, null, 2)}`);
153+
}
154+
return objAfter;
155+
});
156+
}
157+
registerScriptlet(jsonEditFn, {
158+
name: 'json-edit.fn',
159+
dependencies: [
160+
JSONPath,
161+
proxyApplyFn,
162+
safeSelf,
163+
],
164+
});
165+
130166
/******************************************************************************/
131167
/**
132168
* @scriptlet json-edit.js
@@ -138,15 +174,20 @@ registerScriptlet(trustedEditOutboundObject, {
138174
* @param jsonq
139175
* A uBO-flavored JSONPath query.
140176
*
177+
* @param 'matches', pattern
178+
* Vararg, optional: The JSONPath will be applied if and only if the pattern
179+
* matches the inbound JSON string. The pattern can be a plain string or a
180+
* regex.
181+
*
141182
* */
142183

143-
function jsonEdit(jsonq = '') {
144-
editOutboundObjectFn(false, 'JSON.parse', jsonq);
184+
function jsonEdit(jsonq = '', ...varargs) {
185+
jsonEditFn(false, jsonq, ...varargs);
145186
}
146187
registerScriptlet(jsonEdit, {
147188
name: 'json-edit.js',
148189
dependencies: [
149-
editOutboundObjectFn,
190+
jsonEditFn,
150191
],
151192
});
152193

@@ -161,16 +202,21 @@ registerScriptlet(jsonEdit, {
161202
* @param jsonq
162203
* A uBO-flavored JSONPath query.
163204
*
205+
* @param 'matches', pattern
206+
* Vararg, optional: The JSONPath will be applied if and only if the pattern
207+
* matches the inbound JSON string. The pattern can be a plain string or a
208+
* regex.
209+
*
164210
* */
165211

166-
function trustedJsonEdit(jsonq = '') {
167-
editOutboundObjectFn(true, 'JSON.parse', jsonq);
212+
function trustedJsonEdit(jsonq = '', ...varargs) {
213+
jsonEditFn(true, jsonq, ...varargs);
168214
}
169215
registerScriptlet(trustedJsonEdit, {
170216
name: 'trusted-json-edit.js',
171217
requiresTrust: true,
172218
dependencies: [
173-
editOutboundObjectFn,
219+
jsonEditFn,
174220
],
175221
});
176222

0 commit comments

Comments
 (0)