UNPKG

8.41 kBJavaScriptView Raw
1var path = require( 'path' ),
2 fs = require( 'fs' ),
3 engineStrict = require( 'engine-strict' ),
4 readline = require( 'readline-sync' ),
5 argv = require( 'yargs' ).argv,
6 request = require( 'request-promise' ),
7 mustache = require( 'mustache' ),
8 Excel = require( 'exceljs' ),
9 Ssh2SftpClient = require( 'ssh2-sftp-client' ),
10 Tmp = require( 'tmp' ),
11 striptags = require( 'striptags' );
12
13var keytarServiceName = 'bipsync-apiclient';
14
15var initialWorkingDirectory;
16if ( process.cwd() != __dirname ) {
17 initialWorkingDirectory = process.cwd();
18 process.chdir( __dirname );
19}
20engineStrict.check();
21if ( initialWorkingDirectory ) {
22 process.chdir( initialWorkingDirectory );
23}
24
25var keytar;
26try {
27 keytar = require( 'keytar' );
28}
29catch ( error ) {
30 // keytar not installed (optional)
31 keytar = null;
32 console.error( 'keytar is not installed, tokens will not be stored' );
33}
34
35var APIClientExport = module.exports = function APIClientExport( apiUrl ) {
36
37 var createAPIClientWithToken = function( apiUrl, token ) {
38
39 return new APIClient( {
40 requestDefaults : {
41 baseUrl : apiUrl,
42 headers : {
43 Token : token
44 },
45 json : true
46 }
47 } );
48
49 };
50
51 return new Promise( function( resolve, reject ) {
52
53 apiUrl = argv.apiAppUrl || apiUrl;
54 if ( !apiUrl ) {
55 console.error( 'Error: please specify the API URL' );
56 reject();
57 }
58
59 if ( argv.token ) {
60 var client = createAPIClientWithToken( apiUrl, argv.token );
61 resolve( client );
62 }
63 else if ( keytar ) {
64 keytar.getPassword( keytarServiceName, apiUrl ).then( function( token ) {
65
66 if ( !token || argv.resetApiToken ) {
67 token = readline.question( 'API Token (' + apiUrl + '): ', { hideEchoBack : true } );
68 if ( !token ) {
69 console.error( 'Error: an API Token is required' );
70 return;
71 }
72 if ( !keytar.setPassword( keytarServiceName, apiUrl, token ) ) {
73 console.error( 'Error: failed to store API Token' );
74 return;
75 }
76 }
77
78 var client = createAPIClientWithToken( apiUrl, token );
79 resolve( client );
80
81 } );
82 }
83 else {
84
85 console.error( 'Error: an API Token is required' );
86 return;
87 }
88
89 } );
90
91};
92
93APIClientExport.setApiUrlToken = function( apiUrl, token ) {
94
95 if ( keytar ) {
96 keytar.setPassword( keytarServiceName, apiUrl, token );
97 }
98
99};
100
101APIClientExport.generateReportTool = function( options ) {
102
103 if ( argv.getOptions ) {
104 var schema = options.schema || {},
105 uiSchema = options.uiSchema || {},
106 formats = options.formats || [];
107
108 process.stdout.write( JSON.stringify( {
109 schema : schema,
110 uiSchema : uiSchema,
111 formats : formats
112 } ) );
113 process.exit();
114 }
115
116 var stdinData = '';
117 process.stdin.on( 'readable', function() {
118 var stdinChunk = this.read();
119 if ( stdinChunk === null ) {
120 if ( !stdinData.length ) {
121 options.fetch();
122 }
123 this.pause();
124 }
125 else {
126 stdinData += stdinChunk;
127 }
128 } );
129
130 var templateFromPath = function( templatePath ) {
131 return fs.readFileSync(
132 path.join( __dirname, templatePath ), {
133 encoding: 'utf8' } );
134 };
135
136 process.stdin.on( 'end', function() {
137
138 if ( !stdinData.length ) {
139 return;
140 }
141 if ( options.render ) {
142
143 var workbook = null;
144 getExcelStream = function() {
145 return new Excel.stream.xlsx.WorkbookWriter( {
146 stream : process.stdout,
147 useStyles : true
148 } );
149 },
150 firstCSVLine = true;
151
152 options.render( {
153 log : function( message ) {
154 process.stderr.write( message + "\n" );
155 },
156 outputCSVLine : function( columns ) {
157
158 if ( firstCSVLine ) {
159 process.stdout.write( '\ufeff' );
160 firstCSVLine = false;
161 }
162 columns = columns.map( function( column ) {
163 column = column.replace( /[\s\t\r\n]/g, ' ' );
164 if ( column.indexOf( ',' ) != -1 ) {
165 return '"' + column.replace( /"/g, '""' ) + '"';
166 }
167 return column;
168 } );
169 process.stdout.write( columns.join( ',' ) + '\n' );
170
171 },
172 getExcelWorksheet : function( name ) {
173 if ( !workbook ) {
174 workbook = getExcelStream();
175 }
176 return workbook.addWorksheet( name );
177 },
178 commitWorkbook() {
179 workbook.commit();
180 },
181 renderMustacheTemplate( templateString, view, includeJs ) {
182
183 includeJs = includeJs || false;
184
185 var templateString = '{{> reportTop}}' + templateString + '{{> reportBottom}}',
186 partials = {
187 reportTop : templateFromPath( 'reportTop.html' ),
188 reportCss : templateFromPath( 'report.css' ),
189 reportBottom : templateFromPath( 'reportBottom.html' )
190 };
191
192 if ( includeJs ) {
193 partials.reportJs = templateFromPath( 'report.js' );
194 }
195
196 return mustache.render(
197 templateString,
198 view,
199 partials
200 );
201
202 }
203 }, JSON.parse( stdinData ) );
204 }
205 else {
206 var templateString = options.template;
207 templateString = '{{> reportTop}}' + templateString + '{{> reportBottom}}';
208
209 var outputString = mustache.render(
210 templateString,
211 JSON.parse( stdinData ),
212 {
213 reportTop : templateFromPath( 'reportTop.html' ),
214 reportCss : templateFromPath( 'report.css' ),
215 reportJs : templateFromPath( 'report.js' ),
216 reportBottom : templateFromPath( 'reportBottom.html' )
217 } );
218
219 process.stdout.write( outputString );
220 }
221
222 } );
223
224};
225
226APIClientExport.Ssh2SftpClient = Ssh2SftpClient;
227
228APIClientExport.Tmp = Tmp;
229
230class APIClient {
231
232 constructor( options ) {
233
234 options = options || {};
235
236 this.argv = argv;
237
238 if ( this.argv.options ) {
239 this.options = JSON.parse( this.argv.options );
240 delete this.argv.options;
241 }
242
243 this.request = request.defaults( options.requestDefaults || {} );
244
245 }
246
247 requestAll( url, options ) {
248 var allResults = [];
249 options = options || {};
250 options.body = options.body || {};
251 return new Promise( function( resolve ) {
252 var offset = 0,
253 next = function() {
254 options.body.offset = offset;
255 return this.request( url, options )
256 .then( function( page ) {
257 if ( page.results.length ) {
258 offset += page.limit;
259 allResults = allResults.concat( page.results );
260 return next();
261 }
262 else {
263 resolve( allResults );
264 }
265 } );
266 }.bind( this );
267 return next();
268 }.bind( this ) );
269 }
270
271 output( data ) {
272
273 process.stdout.write( JSON.stringify( data, null, 2 ) );
274
275 }
276
277 log( message ) {
278
279 process.stderr.write( message + "\n" );
280
281 }
282
283}