UNPKG

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