@@ -656,12 +656,18 @@ interface SerializedPassThroughData {
656656 lookupOptions ?: PassThroughLookupOptions ;
657657
658658 transformRequest ?: Replace <
659- Replace < RequestTransform , 'replaceBody' , string | undefined > , // Serialized as base64 buffer
660- 'updateJsonBody' , string | undefined // Serialized as a string to preserve undefined values
659+ RequestTransform ,
660+ | 'replaceBody' // Serialized as base64 buffer
661+ | 'updateHeaders' // // Serialized as a string to preserve undefined values
662+ | 'updateJsonBody' , // Serialized as a string to preserve undefined values
663+ string | undefined
661664 > ,
662665 transformResponse ?: Replace <
663- Replace < ResponseTransform , 'replaceBody' , string | undefined > , // Serialized as base64 buffer
664- 'updateJsonBody' , string | undefined // Serialized as a string to preserve undefined values
666+ ResponseTransform ,
667+ | 'replaceBody' // Serialized as base64 buffer
668+ | 'updateHeaders' // // Serialized as a string to preserve undefined values
669+ | 'updateJsonBody' , // Serialized as a string to preserve undefined values
670+ string | undefined
665671 > ,
666672
667673 hasBeforeRequestCallback ?: boolean ;
@@ -852,6 +858,17 @@ function validateCustomHeaders(
852858const OMIT_SYMBOL = Symbol ( 'omit-value' ) ;
853859const SERIALIZED_OMIT = "__mockttp__transform__omit__" ;
854860
861+ // We play some games to preserve undefined values during serialization, because we differentiate them
862+ // in some transforms from null/not-present keys.
863+ const mapOmitToUndefined = < T extends { [ key : string ] : any } > (
864+ input : T
865+ ) : { [ K in keyof T ] : T [ K ] | undefined } =>
866+ _ . mapValues ( input , ( v ) =>
867+ v === SERIALIZED_OMIT || v === OMIT_SYMBOL
868+ ? undefined // Replace our omit placeholders with actual undefineds
869+ : v
870+ ) ;
871+
855872export class PassThroughHandler extends Serializable implements RequestHandler {
856873 readonly type = 'passthrough' ;
857874
@@ -1509,10 +1526,17 @@ export class PassThroughHandler extends Serializable implements RequestHandler {
15091526 ) ,
15101527 transformRequest : {
15111528 ...this . transformRequest ,
1529+ // Body is always serialized as a base64 buffer:
15121530 replaceBody : ! ! this . transformRequest ?. replaceBody
1513- // Always serialize as a base64 buffer:
15141531 ? serializeBuffer ( asBuffer ( this . transformRequest . replaceBody ) )
15151532 : undefined ,
1533+ // Update objects need to capture undefined & null as distict values:
1534+ updateHeaders : ! ! this . transformRequest ?. updateHeaders
1535+ ? JSON . stringify (
1536+ this . transformRequest . updateHeaders ,
1537+ ( k , v ) => v === undefined ? SERIALIZED_OMIT : v
1538+ )
1539+ : undefined ,
15161540 updateJsonBody : ! ! this . transformRequest ?. updateJsonBody
15171541 ? JSON . stringify (
15181542 this . transformRequest . updateJsonBody ,
@@ -1522,10 +1546,17 @@ export class PassThroughHandler extends Serializable implements RequestHandler {
15221546 } ,
15231547 transformResponse : {
15241548 ...this . transformResponse ,
1549+ // Body is always serialized as a base64 buffer:
15251550 replaceBody : ! ! this . transformResponse ?. replaceBody
1526- // Always serialize as a base64 buffer:
15271551 ? serializeBuffer ( asBuffer ( this . transformResponse . replaceBody ) )
15281552 : undefined ,
1553+ // Update objects need to capture undefined & null as distict values:
1554+ updateHeaders : ! ! this . transformResponse ?. updateHeaders
1555+ ? JSON . stringify (
1556+ this . transformResponse . updateHeaders ,
1557+ ( k , v ) => v === undefined ? SERIALIZED_OMIT : v
1558+ )
1559+ : undefined ,
15291560 updateJsonBody : ! ! this . transformResponse ?. updateJsonBody
15301561 ? JSON . stringify (
15311562 this . transformResponse . updateJsonBody ,
@@ -1581,25 +1612,25 @@ export class PassThroughHandler extends Serializable implements RequestHandler {
15811612 ...( data . transformRequest ?. replaceBody !== undefined ? {
15821613 replaceBody : deserializeBuffer ( data . transformRequest . replaceBody )
15831614 } : { } ) ,
1615+ ...( data . transformRequest ?. updateHeaders !== undefined ? {
1616+ updateHeaders : mapOmitToUndefined ( JSON . parse ( data . transformRequest . updateHeaders ) )
1617+ } : { } ) ,
15841618 ...( data . transformRequest ?. updateJsonBody !== undefined ? {
1585- updateJsonBody : JSON . parse (
1586- data . transformRequest . updateJsonBody ,
1587- ( k , v ) => v === SERIALIZED_OMIT ? OMIT_SYMBOL : v
1588- )
1619+ updateJsonBody : mapOmitToUndefined ( JSON . parse ( data . transformRequest . updateJsonBody ) )
15891620 } : { } ) ,
1590- } ,
1621+ } as RequestTransform ,
15911622 transformResponse : {
15921623 ...data . transformResponse ,
15931624 ...( data . transformResponse ?. replaceBody !== undefined ? {
15941625 replaceBody : deserializeBuffer ( data . transformResponse . replaceBody )
15951626 } : { } ) ,
1627+ ...( data . transformResponse ?. updateHeaders !== undefined ? {
1628+ updateHeaders : mapOmitToUndefined ( JSON . parse ( data . transformResponse . updateHeaders ) )
1629+ } : { } ) ,
15961630 ...( data . transformResponse ?. updateJsonBody !== undefined ? {
1597- updateJsonBody : JSON . parse (
1598- data . transformResponse . updateJsonBody ,
1599- ( k , v ) => v === SERIALIZED_OMIT ? OMIT_SYMBOL : v
1600- )
1631+ updateJsonBody : mapOmitToUndefined ( JSON . parse ( data . transformResponse . updateJsonBody ) )
16011632 } : { } )
1602- } ,
1633+ } as ResponseTransform ,
16031634 // Backward compat for old clients:
16041635 ...data . forwardToLocation ? {
16051636 forwarding : { targetHost : data . forwardToLocation }
0 commit comments