• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/**************************************************************************************************
2 * EJDB2 Node.js native API binding.
3 *
4 * MIT License
5 *
6 * Copyright (c) 2012-2022 Softmotions Ltd <info@softmotions.com>
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 *  copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included in all
16 * copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 * SOFTWARE.
25 *************************************************************************************************/
26
27const fs = require('fs');
28const request = require('request');
29const progress = require('request-progress');
30const Gauge = require('gauge');
31const childProcess = require('child_process');
32
33let platform = process.platform.toLowerCase();
34if (platform.indexOf('win') === 0) {
35  platform = 'windows';
36}
37
38/**
39 * @param {String} name
40 * @param {Array<String>} [args]
41 * @param {String} [cwd]
42 * @return {Promise<void>}
43 */
44function runProcess(name, args, cwd) {
45  args = args || [];
46  console.log(`Spawn: ${name} ${args}`);
47  return awaitProcess(childProcess.spawn(name, args, {
48    stdio: ['ignore', process.stdout, process.stderr],
49    cwd
50  }));
51}
52
53function runProcessAndGetOutput(name, args, cwd) {
54  const res = [];
55  args = args || [];
56  console.log(`Spawn: ${name} ${args}`);
57  const proc = childProcess.spawn(name, args, {
58    stdio: ['ignore', 'pipe', 'pipe'],
59    cwd
60  });
61  proc.stdout.on('data', (data) => res.push(data));
62  proc.stderr.on('data', (data) => res.push(data));
63  return awaitProcess(proc).then(() => {
64    return res.join();
65  });
66}
67
68/**
69 * @return {Promise<void>}
70 */
71function awaitProcess(childProcess) {
72  return new Promise((resolve, reject) => {
73    childProcess.once('exit', (code) => {
74      if (code === 0) {
75        resolve(undefined);
76      } else {
77        reject(new Error('Exit with error code: ' + code));
78      }
79    });
80    childProcess.once('error', (err) => reject(err));
81  });
82}
83
84/**
85 * @param {String} url
86 * @param {String} dest
87 * @return {Promise<String>}
88 */
89function download(url, dest, name) {
90  const gauge = new Gauge();
91  return new Promise((resolve, reject) => {
92    let completed = false;
93    function handleError(err) {
94      if (!completed) {
95        gauge.hide();
96        reject(err);
97        completed = true;
98      }
99    }
100    progress(request(url), {
101      throttle: 500,
102      delay: 0
103    })
104      .on('progress', (state) => gauge.show(name || url, state.percent))
105      .on('error', (err) => handleError(err))
106      .on('end', () => {
107        if (!completed) {
108          gauge.hide();
109          resolve(dest);
110          completed = true;
111        }
112      })
113      .on('response', function (response) {
114        if (response.statusCode >= 400) {
115          handleError(`HTTP ${response.statusCode}: ${url}`);
116        }
117      })
118      .pipe(fs.createWriteStream(dest));
119  });
120}
121
122module.exports = {
123  binariesDir: `${platform}-${process.arch}`,
124  download,
125  awaitProcess,
126  runProcess,
127  runProcessAndGetOutput
128};
129