@@ -99,12 +99,19 @@ export class JSONPath {
99
99
const r = this . #compile( query , 0 ) ;
100
100
if ( r === undefined ) { return ; }
101
101
if ( r . i !== query . length ) {
102
- if ( query . startsWith ( '+=' , r . i ) ) {
102
+ let val ;
103
+ if ( query . startsWith ( '=' , r . i ) ) {
104
+ if ( / ^ = r e p l \( .+ \) $ / . test ( query . slice ( r . i ) ) ) {
105
+ r . modify = 'repl' ;
106
+ val = query . slice ( r . i + 6 , - 1 ) ;
107
+ } else {
108
+ val = query . slice ( r . i + 1 ) ;
109
+ }
110
+ } else if ( query . startsWith ( '+=' , r . i ) ) {
103
111
r . modify = '+' ;
104
- r . i += 1 ;
112
+ val = query . slice ( r . i + 2 ) ;
105
113
}
106
- if ( query . startsWith ( '=' , r . i ) === false ) { return ; }
107
- try { r . rval = JSON . parse ( query . slice ( r . i + 1 ) ) ; }
114
+ try { r . rval = JSON . parse ( val ) ; }
108
115
catch { return ; }
109
116
}
110
117
this . #compiled = r ;
@@ -118,19 +125,15 @@ export class JSONPath {
118
125
}
119
126
apply ( root ) {
120
127
if ( this . valid === false ) { return 0 ; }
121
- const { modify , rval } = this . #compiled;
128
+ const { rval } = this . #compiled;
122
129
this . #root = root ;
123
130
const paths = this . #evaluate( this . #compiled. steps , [ ] ) ;
124
131
const n = paths . length ;
125
132
let i = n ;
126
133
while ( i -- ) {
127
134
const { obj, key } = this . #resolvePath( paths [ i ] ) ;
128
135
if ( rval !== undefined ) {
129
- if ( modify === '+' ) {
130
- this . #modifyVal( obj , key , rval ) ;
131
- } else {
132
- obj [ key ] = rval ;
133
- }
136
+ this . #modifyVal( obj , key ) ;
134
137
} else if ( Array . isArray ( obj ) && typeof key === 'number' ) {
135
138
obj . splice ( key , 1 ) ;
136
139
} else {
@@ -458,13 +461,40 @@ export class JSONPath {
458
461
}
459
462
if ( outcome ) { return k ; }
460
463
}
461
- #modifyVal( obj , key , rval ) {
462
- const lval = obj [ key ] ;
463
- if ( rval instanceof Object === false ) { return ; }
464
- if ( lval instanceof Object === false ) { return ; }
465
- if ( Array . isArray ( lval ) ) { return ; }
466
- for ( const [ k , v ] of Object . entries ( rval ) ) {
467
- lval [ k ] = v ;
464
+ #modifyVal( obj , key ) {
465
+ const { modify, rval } = this . #compiled;
466
+ switch ( modify ) {
467
+ case undefined :
468
+ obj [ key ] = rval ;
469
+ break ;
470
+ case '+' : {
471
+ if ( rval instanceof Object === false ) { return ; }
472
+ const lval = obj [ key ] ;
473
+ if ( lval instanceof Object === false ) { return ; }
474
+ if ( Array . isArray ( lval ) ) { return ; }
475
+ for ( const [ k , v ] of Object . entries ( rval ) ) {
476
+ lval [ k ] = v ;
477
+ }
478
+ break ;
479
+ }
480
+ case 'repl' : {
481
+ const lval = obj [ key ] ;
482
+ if ( typeof lval !== 'string' ) { return ; }
483
+ if ( this . #compiled. re === undefined ) {
484
+ this . #compiled. re = null ;
485
+ try {
486
+ this . #compiled. re = rval . regex !== undefined
487
+ ? new RegExp ( rval . regex , rval . flags )
488
+ : new RegExp ( rval . pattern . replace ( / [ . * + ? ^ $ { } ( ) | [ \] \\ ] / g, '\\$&' ) ) ;
489
+ } catch {
490
+ }
491
+ }
492
+ if ( this . #compiled. re === null ) { return ; }
493
+ obj [ key ] = lval . replace ( this . #compiled. re , rval . replacement ) ;
494
+ break ;
495
+ }
496
+ default :
497
+ break ;
468
498
}
469
499
}
470
500
}
0 commit comments