@@ -50,6 +50,7 @@ import {
5050import { DecodedUserObject } from "@src/types/fastify" ;
5151import { EncryptionService } from "@src/modules/common/services/encryption.service" ;
5252import { VariableDto } from "@src/modules/common/models/environment.model" ;
53+ import { RequestBodyDto } from "@src/modules/common/models/collection.model" ;
5354
5455@Injectable ( )
5556export class CollectionService {
@@ -1142,35 +1143,88 @@ export class CollectionService {
11421143 generatedVariables : VariableDto [ ] ,
11431144 requestItem : any ,
11441145 ) : any {
1145- // Recursive function to deeply replace matches
1146- const replaceValues = ( obj : any , path : string = "" ) : any => {
1147- if ( Array . isArray ( obj ) ) {
1148- return obj . map ( ( item , index ) =>
1149- replaceValues ( item , `${ path } [${ index } ]` ) ,
1150- ) ;
1151- } else if ( obj && typeof obj === "object" ) {
1152- const newObj : any = { } ;
1153- for ( const [ key , value ] of Object . entries ( obj ) ) {
1154- newObj [ key ] = replaceValues ( value , `${ path } .${ key } ` ) ;
1155- }
1156- return newObj ;
1157- } else if ( typeof obj === "string" ) {
1158- for ( const variable of generatedVariables ) {
1159- if ( obj === variable . value ) {
1160- return `{{${ variable . key } }}` ;
1146+ // Helper: replace only outside {{ }} blocks
1147+ const replaceOutsideBraces = ( text : string ) : string => {
1148+ return text . replace (
1149+ / ( \{ \{ .* ?\} \} ) | ( [ ^ { } ] + ) / g,
1150+ ( match , insideBraces , outside ) => {
1151+ if ( insideBraces ) return insideBraces ;
1152+ let updated = outside ;
1153+ for ( const variable of generatedVariables ) {
1154+ if ( updated === variable . value ) {
1155+ updated = `{{${ variable . key } }}` ;
1156+ } else if ( updated . includes ( variable . value ) ) {
1157+ updated = updated . replace (
1158+ new RegExp ( variable . value , "g" ) ,
1159+ `{{${ variable . key } }}` ,
1160+ ) ;
1161+ }
1162+ }
1163+ return updated ;
1164+ } ,
1165+ ) ;
1166+ } ;
1167+
1168+ // Special updater for array of key-value objects
1169+ const updateKeyValueArray = ( arr : any [ ] ) => {
1170+ return arr . map ( ( entry ) => ( {
1171+ ...entry ,
1172+ key :
1173+ typeof entry . key === "string"
1174+ ? replaceOutsideBraces ( entry . key )
1175+ : entry . key ,
1176+ value :
1177+ typeof entry . value === "string"
1178+ ? replaceOutsideBraces ( entry . value )
1179+ : entry . value ,
1180+ } ) ) ;
1181+ } ;
1182+
1183+ // Main recursive update
1184+ const replaceValues = ( obj : any ) : any => {
1185+ if ( ! obj || typeof obj !== "object" ) {
1186+ return typeof obj === "string" ? replaceOutsideBraces ( obj ) : obj ;
1187+ }
1188+ const newObj : any = Array . isArray ( obj ) ? [ ] : { } ;
1189+ for ( const [ key , value ] of Object . entries ( obj ) ) {
1190+ if ( key === "url" && typeof value === "string" ) {
1191+ newObj [ key ] = replaceOutsideBraces ( value ) ;
1192+ } else if ( key === "headers" && Array . isArray ( value ) ) {
1193+ newObj [ key ] = updateKeyValueArray ( value ) ;
1194+ } else if ( key === "queryParams" && Array . isArray ( value ) ) {
1195+ newObj [ key ] = updateKeyValueArray ( value ) ;
1196+ } else if (
1197+ key === "body" &&
1198+ typeof value === "object" &&
1199+ value !== null
1200+ ) {
1201+ const updatedBody = { ...( value as RequestBodyDto ) } ;
1202+ if ( typeof updatedBody . raw === "string" ) {
1203+ updatedBody . raw = replaceOutsideBraces ( updatedBody . raw ) ;
11611204 }
1162- if ( obj . includes ( variable . value ) ) {
1163- obj = obj . replace (
1164- new RegExp ( variable . value , "g" ) ,
1165- `{{${ variable . key } }}` ,
1205+ if ( Array . isArray ( updatedBody . urlencoded ) ) {
1206+ updatedBody . urlencoded = updateKeyValueArray (
1207+ updatedBody . urlencoded ,
11661208 ) ;
11671209 }
1210+ if (
1211+ updatedBody . formdata &&
1212+ typeof updatedBody . formdata === "object"
1213+ ) {
1214+ if ( Array . isArray ( updatedBody . formdata . text ) ) {
1215+ updatedBody . formdata . text = updateKeyValueArray (
1216+ updatedBody . formdata . text ,
1217+ ) ;
1218+ }
1219+ }
1220+ newObj [ key ] = updatedBody ;
1221+ } else {
1222+ newObj [ key ] = replaceValues ( value ) ;
11681223 }
1169- return obj ;
11701224 }
1171- return obj ;
1225+ return newObj ;
11721226 } ;
1173- return replaceValues ( requestItem , "root" ) ;
1227+ return replaceValues ( requestItem ) ;
11741228 }
11751229
11761230 public async insertGeneratedVariables (
@@ -1190,17 +1244,30 @@ export class CollectionService {
11901244 }
11911245 const traverseAndUpdate = ( items : any [ ] ) => {
11921246 for ( const item of items ) {
1193- if (
1194- item . type === ItemTypeEnum . REQUEST ||
1195- item . type === ItemTypeEnum . GRAPHQL ||
1196- item . type === ItemTypeEnum . SOCKETIO ||
1197- item . type === ItemTypeEnum . WEBSOCKET
1198- ) {
1247+ if ( item . type === ItemTypeEnum . REQUEST ) {
11991248 item . request = this . updatedRequestInCollection (
12001249 generatedPairs ,
12011250 item . request ,
12021251 ) ;
12031252 }
1253+ if ( item . type === ItemTypeEnum . SOCKETIO ) {
1254+ item . socketio = this . updatedRequestInCollection (
1255+ generatedPairs ,
1256+ item . socketio ,
1257+ ) ;
1258+ }
1259+ if ( item . type === ItemTypeEnum . WEBSOCKET ) {
1260+ item . websocket = this . updatedRequestInCollection (
1261+ generatedPairs ,
1262+ item . websocket ,
1263+ ) ;
1264+ }
1265+ if ( item . type === ItemTypeEnum . GRAPHQL ) {
1266+ item . graphql = this . updatedRequestInCollection (
1267+ generatedPairs ,
1268+ item . graphql ,
1269+ ) ;
1270+ }
12041271 // If folder or item has nested items
12051272 if ( Array . isArray ( item . items ) && item . items . length > 0 ) {
12061273 traverseAndUpdate ( item . items ) ;
0 commit comments