1+ #!/usr/bin/env python3
2+
3+ import json
4+ import os
5+ import sys
6+ from pathlib import Path
7+ from typing import Dict , List , Set
8+
9+ # Properties to remove from Postman files
10+ METADATA_PROPERTIES = {
11+ '_postman_id' ,
12+ '_exporter_id' ,
13+ 'id' ,
14+ 'uid' ,
15+ 'owner' ,
16+ 'createdAt' ,
17+ 'updatedAt' ,
18+ 'lastUpdatedBy' ,
19+ 'lastRevision' ,
20+ }
21+
22+ # Required schema versions for Postman files
23+ COLLECTION_SCHEMA = "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
24+ ENVIRONMENT_SCHEMA = "https://schema.getpostman.com/json/environment/v1.0.0/environment.json"
25+
26+ def remove_metadata (data : Dict , properties : Set [str ]) -> Dict :
27+ """Recursively remove specified properties from a dictionary."""
28+ if not isinstance (data , dict ):
29+ return data
30+
31+ result = {}
32+ for key , value in data .items ():
33+ if key in properties :
34+ continue
35+
36+ if isinstance (value , dict ):
37+ result [key ] = remove_metadata (value , properties )
38+ elif isinstance (value , list ):
39+ result [key ] = [remove_metadata (item , properties ) if isinstance (item , dict ) else item for item in value ]
40+ else :
41+ result [key ] = value
42+
43+ return result
44+
45+ def sanitize_file (file_path : Path ) -> bool :
46+ """Sanitize a single Postman file and return True if changes were made."""
47+ try :
48+ with open (file_path , 'r' , encoding = 'utf-8' ) as f :
49+ data = json .load (f )
50+
51+ # Preserve the original schema
52+ original_schema = data .get ('info' , {}).get ('schema' ) if 'info' in data else data .get ('schema' )
53+
54+ # Remove metadata
55+ sanitized_data = remove_metadata (data , METADATA_PROPERTIES )
56+
57+ # Restore schema if it was present
58+ if original_schema :
59+ if 'info' in sanitized_data :
60+ sanitized_data ['info' ]['schema' ] = original_schema
61+ else :
62+ sanitized_data ['schema' ] = original_schema
63+
64+ # Format the JSON with consistent indentation
65+ new_data = json .dumps (sanitized_data , indent = 2 )
66+
67+ # Compare the sanitized data with original
68+ original_data = json .dumps (data , indent = 2 )
69+ if original_data != new_data :
70+ with open (file_path , 'w' , encoding = 'utf-8' ) as f :
71+ f .write (new_data )
72+ return True
73+ return False
74+ except Exception as e :
75+ print (f"Error processing { file_path } : { str (e )} " , file = sys .stderr )
76+ return False
77+
78+ def find_postman_files (directory : Path ) -> List [Path ]:
79+ """Find all Postman collection and environment files in the directory."""
80+ patterns = ['*.postman_collection.json' , '*.postman_environment.json' ]
81+ files = []
82+ for pattern in patterns :
83+ files .extend (directory .rglob (pattern ))
84+ return files
85+
86+ def main ():
87+ if len (sys .argv ) != 2 :
88+ print ("Usage: python sanitize_postman.py <directory>" )
89+ sys .exit (1 )
90+
91+ directory = Path (sys .argv [1 ])
92+ if not directory .exists ():
93+ print (f"Directory { directory } does not exist" , file = sys .stderr )
94+ sys .exit (1 )
95+
96+ modified_files = []
97+ for file_path in find_postman_files (directory ):
98+ if sanitize_file (file_path ):
99+ modified_files .append (str (file_path ))
100+
101+ if modified_files :
102+ print ("Modified files:" )
103+ for file in modified_files :
104+ print (f"- { file } " )
105+ sys .exit (0 )
106+ else :
107+ print ("No files were modified" )
108+ sys .exit (0 )
109+
110+ if __name__ == '__main__' :
111+ main ()
0 commit comments