@@ -5,71 +5,127 @@ var apiMocker = require('connect-api-mocker');
55var bodyParser = require ( 'body-parser' )
66var proxy = require ( 'http-proxy-middleware' ) ;
77var cors = require ( 'cors' ) ;
8+ var fs = require ( 'fs' ) ;
9+ var pth = require ( 'path' ) ;
10+ var mkdirp = require ( 'mkdirp' ) ;
811var commandLineArgs = require ( 'command-line-args' ) ;
912var defaultPortValue = 9090 ;
1013var defaultFromPathValue = '/' ;
1114var defaultToPathValue = '' ;
1215var optionDefinitions = [
1316 { name : 'port' , alias : 'p' , type : Number , defaultValue : defaultPortValue } ,
1417 { name : 'fromPath' , alias : 'f' , type : String , defaultValue : defaultFromPathValue } ,
15- { name : 'toPath' , alias : 't' , type : String , defaultValue : defaultToPathValue }
18+ { name : 'toPath' , alias : 't' , type : String , defaultValue : defaultToPathValue } ,
19+ { name : 'capture' , alias : 'c' , type : Boolean , defaultValue : false } ,
20+ { name : 'verbose' , alias : 'v' , type : Boolean , defaultValue : false }
1621] ;
1722
23+ function escapeRegExp ( str ) {
24+ return str . replace ( / [ \- \[ \] \/ \{ \} \( \) \* \+ \? \. \\ \^ \$ \| ] / g, "\\$&" ) ;
25+ }
26+
1827var options = commandLineArgs ( optionDefinitions ) ;
1928
2029var app = express ( ) ;
2130
2231var mapping = { } ;
2332
24- mapping [ options . fromPath ] = options . toPath ;
33+ mapping [ options . fromPath ] = {
34+ target : options . toPath
35+ } ;
2536
2637var defaultConfig = {
27- port : options . port ,
28- map : mapping
38+ port : options . port ,
39+ map : mapping
2940} ;
3041var config = defaultConfig ;
3142
3243try {
33- var loadedConfig = require ( path . resolve ( process . cwd ( ) , 'mock.config.js' ) ) ;
34- console . log ( 'Config file found mocking!' ) ;
44+ var loadedConfig = require ( path . resolve ( process . cwd ( ) , 'mock.config.js' ) ) ;
45+ console . log ( 'Config file found mocking!' ) ;
3546
36- if ( config . port === defaultPortValue && loadedConfig . port ) {
37- config . port = loadedConfig . port ;
38- }
47+ if ( config . port === defaultPortValue && loadedConfig . port ) {
48+ config . port = loadedConfig . port ;
49+ }
3950
40- var mapKeys = Object . keys ( config . map ) ;
41- if ( loadedConfig . map ) {
42- mapKeys . forEach ( function ( mapKey ) {
43- loadedConfig . map [ mapKey ] = config . map [ mapKey ] ;
44- } ) ;
45- config . map = loadedConfig . map ;
46- }
51+ var mapKeys = Object . keys ( config . map ) ;
52+ if ( loadedConfig . map ) {
53+ mapKeys . forEach ( function ( mapKey ) {
54+ loadedConfig . map [ mapKey ] = config . map [ mapKey ] ;
55+ } ) ;
56+ config . map = loadedConfig . map ;
57+ }
4758} catch ( error ) {
48- // there is no config
59+ // there is no config
4960}
5061
51- app . use ( cors ( ) )
62+ if ( options . verbose ) {
63+ Object . keys ( config . map ) . forEach ( function ( key ) {
64+ config . map [ key ] . verbose = true ;
65+ } ) ;
66+ }
5267
53- for ( var path in config . map ) {
68+ app . use ( cors ( ) ) ;
5469
55- var conf = config . map [ path ] ;
70+ for ( var path in config . map ) {
71+ ( function ( basePath ) {
72+ var conf = config . map [ basePath ] ;
5673
5774 if ( conf . proxy ) {
58- conf . nextOnNotFound = true ;
75+ conf . nextOnNotFound = true ;
5976 }
6077
61- app . use ( path , apiMocker ( conf ) ) ;
62- console . log ( `Mocking enabled: ${ path } => ${ conf } ` ) ;
78+ app . use ( basePath , apiMocker ( conf ) ) ;
79+ console . log ( `Mocking enabled: ${ basePath } => ${ conf . target || conf } ` ) ;
6380
6481 if ( conf . proxy ) {
65- console . log ( `Proxy enabled: ${ path } => ${ conf . proxy } ` ) ;
66- if ( typeof conf . proxy == 'string' ) {
67- config . proxy = {
68- target : conf . proxy
69- }
82+ console . log ( `Proxy enabled: ${ basePath } => ${ conf . proxy } ` ) ;
83+ if ( typeof conf . proxy == 'string' ) {
84+ conf . proxy = {
85+ target : conf . proxy
7086 }
71- app . use ( path , proxy ( conf . proxy ) ) ;
87+ }
88+
89+ if ( conf . capture || options . capture ) {
90+ console . log ( 'Capture Mode enabled for mocks!' ) ;
91+
92+ conf . proxy . onProxyRes = function ( proxyRes , req , res ) {
93+ var body = "" ;
94+ if ( proxyRes . statusCode < 404 ) {
95+ proxyRes . on ( 'data' , function ( data ) {
96+ data = data . toString ( 'utf-8' ) ;
97+ body += data ;
98+ } ) ;
99+
100+ proxyRes . on ( 'end' , function ( ) {
101+ var requestedFilePath = req . path . replace ( new RegExp ( '^(\/)?' + escapeRegExp ( basePath ) ) , '' )
102+ var targetPath = pth . join ( conf . target || conf , requestedFilePath ) ;
103+
104+ var contentType = 'json' ;
105+ if ( proxyRes . headers [ 'content-type' ] . indexOf ( 'xml' ) > - 1 ) {
106+ contentType = 'xml' ;
107+ }
108+
109+ mkdirp . sync ( targetPath ) ;
110+
111+ var targetFile = pth . join ( targetPath , req . method + '.' + contentType ) ;
112+
113+ if ( ! fs . existsSync ( targetFile ) ) {
114+ fs . writeFileSync ( targetFile , body ) ;
115+ console . log ( '[Capture Mode] New mock file saved to ' + targetFile ) ;
116+ }
117+ } ) ;
118+ }
119+ }
120+ }
121+
122+ app . use ( basePath , proxy ( conf . proxy ) ) ;
123+ } else {
124+ if ( conf . capture || options . capture ) {
125+ console . error ( 'You can not use capture mode without defining a proxy.' ) ;
126+ }
72127 }
128+ } ) ( path ) ;
73129}
74130
75131app . listen ( config . port , function ( ) {
0 commit comments