@@ -99,12 +99,19 @@ export class JSONPath {
9999 const r = this . #compile( query , 0 ) ;
100100 if ( r === undefined ) { return ; }
101101 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 ) ) {
103111 r . modify = '+' ;
104- r . i += 1 ;
112+ val = query . slice ( r . i + 2 ) ;
105113 }
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 ) ; }
108115 catch { return ; }
109116 }
110117 this . #compiled = r ;
@@ -118,19 +125,15 @@ export class JSONPath {
118125 }
119126 apply ( root ) {
120127 if ( this . valid === false ) { return 0 ; }
121- const { modify , rval } = this . #compiled;
128+ const { rval } = this . #compiled;
122129 this . #root = root ;
123130 const paths = this . #evaluate( this . #compiled. steps , [ ] ) ;
124131 const n = paths . length ;
125132 let i = n ;
126133 while ( i -- ) {
127134 const { obj, key } = this . #resolvePath( paths [ i ] ) ;
128135 if ( rval !== undefined ) {
129- if ( modify === '+' ) {
130- this . #modifyVal( obj , key , rval ) ;
131- } else {
132- obj [ key ] = rval ;
133- }
136+ this . #modifyVal( obj , key ) ;
134137 } else if ( Array . isArray ( obj ) && typeof key === 'number' ) {
135138 obj . splice ( key , 1 ) ;
136139 } else {
@@ -458,13 +461,40 @@ export class JSONPath {
458461 }
459462 if ( outcome ) { return k ; }
460463 }
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 ;
468498 }
469499 }
470500}
0 commit comments