zarro 1.141.5 → 1.141.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,125 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ (function () {
4
+ const fs = require("fs"), path = require("path"), { ZarroError } = requireModule("zarro-error"), ensureFolderExists = require("./ensure-folder-exists").sync, request = require("request"), debug = require("debug")("http-downloader");
5
+ class HttpClient {
6
+ constructor(infoLogFunction, debugLogFunction) {
7
+ this.aborted = false;
8
+ this._downloadSize = -1;
9
+ this._statusSuffix = "";
10
+ this._written = 0;
11
+ this._lastPerc = -1;
12
+ this._info = infoLogFunction || console.log;
13
+ this._debug = debugLogFunction || debug;
14
+ this.assumeDownloadedIfExistsAndSizeMatches = true;
15
+ }
16
+ async exists(url) {
17
+ return new Promise(resolve => {
18
+ request.get(url, (err) => {
19
+ return resolve(!err);
20
+ });
21
+ });
22
+ }
23
+ async download(url, target) {
24
+ if (this._alreadyDownloaded(target)) {
25
+ return target;
26
+ }
27
+ const partFile = `${target}.part`;
28
+ ensureFolderExists(path.dirname(partFile));
29
+ return new Promise((resolve, reject) => {
30
+ this._request = request.get(url, { timeout: 30000 })
31
+ .on("response", (response) => {
32
+ this._debug(`got response: ${JSON.stringify(response)}`);
33
+ this._downloadSize = parseInt(response.headers["content-length"] || "0");
34
+ this._statusSuffix = "% of " + this._humanSize(this._downloadSize);
35
+ })
36
+ .on("error", (e) => {
37
+ this._debug(`got error: ${e}`);
38
+ reject(e);
39
+ })
40
+ .on("data", (data) => {
41
+ this._debug(`got ${data.length} bytes`);
42
+ this._updateStatus(data);
43
+ })
44
+ .on("end", () => {
45
+ this._clear();
46
+ this._rename(resolve, reject, partFile, target);
47
+ }).pipe(fs.createWriteStream(partFile));
48
+ });
49
+ }
50
+ abort() {
51
+ if (this._request) {
52
+ this.aborted = true;
53
+ this._request.abort();
54
+ this._clear();
55
+ }
56
+ }
57
+ _updateStatus(data) {
58
+ if (process.env.SUPPRESS_DOWNLOAD_PROGRESS || process.env.BUILD_NUMBER /* automatically disable at Jenkins CI */) {
59
+ return;
60
+ }
61
+ this._written += data.length;
62
+ const perc = Math.round((100 * this._written) / this._downloadSize);
63
+ if (perc != this._lastPerc) {
64
+ this._writeStatus(perc + this._statusSuffix);
65
+ this._lastPerc = perc;
66
+ }
67
+ }
68
+ _writeStatus(msg) {
69
+ this._clearStatus();
70
+ process.stdout.write(msg);
71
+ }
72
+ _rename(resolve, reject, src, dst, attempts = 0) {
73
+ try {
74
+ this._debug("attempt rename of temp file");
75
+ fs.renameSync(src, dst);
76
+ this._clearStatus();
77
+ this._info(`-> ${dst} download complete!`);
78
+ resolve(dst);
79
+ }
80
+ catch (e) {
81
+ this._debug("rename error:", e);
82
+ if (attempts > 99) {
83
+ reject(new ZarroError(["Unable to rename \"", src, "\" to \"", dst, "\": ", e].join("")));
84
+ }
85
+ else {
86
+ setTimeout(() => {
87
+ this._rename(resolve, reject, src, dst, attempts++);
88
+ }, 100);
89
+ }
90
+ }
91
+ }
92
+ _clearStatus() {
93
+ process.stdout.write("\r \r");
94
+ }
95
+ _humanSize(size) {
96
+ const suffixes = ["b", "kb", "mb", "tb", "pb"];
97
+ for (let i = 0; i < suffixes.length - 1; i++) {
98
+ if (size < 1024) {
99
+ return size.toFixed(2) + suffixes[i];
100
+ }
101
+ size /= 1024;
102
+ }
103
+ return size.toFixed(2) + suffixes[suffixes.length - 1];
104
+ }
105
+ _clear() {
106
+ this._request = undefined;
107
+ this._downloadSize = -1;
108
+ this._lastPerc = -1;
109
+ }
110
+ _alreadyDownloaded(target) {
111
+ if (!this.assumeDownloadedIfExistsAndSizeMatches) {
112
+ return false;
113
+ }
114
+ if (!fs.existsSync(target)) {
115
+ return false;
116
+ }
117
+ const lstat = fs.lstatSync(target);
118
+ return lstat.size === this._downloadSize;
119
+ }
120
+ static create(infoLogFunction, debugLogFunction) {
121
+ return new HttpClient(infoLogFunction, debugLogFunction);
122
+ }
123
+ }
124
+ module.exports = HttpClient;
125
+ })();
@@ -1,113 +1,4 @@
1
- const
2
- fs = require('fs'),
3
- path = require("path"),
4
- ensureFolderExists = require("./ensure-folder-exists").sync,
5
- request = require('request'),
6
- debug = require('debug')('http-downloader');
7
-
8
- function HttpDownloader(infoLogFunction, debugLogFunction) {
9
- this._info = infoLogFunction || console.log;
10
- this._debug = debugLogFunction || debug;
11
- this.assumeDownloadedIfExistsAndSizeMatches = true;
12
- }
13
-
14
- HttpDownloader.prototype = {
15
- download: function (url, target) {
16
- const partFile = `${target}.part`;
17
- ensureFolderExists(path.dirname(partFile));
18
- return new Promise((resolve, reject) => {
19
- this._request = request.get(url, { timeout: 30000 })
20
- .on("response", (response) => {
21
- this._debug(`got response: ${JSON.stringify(response)}`);
22
- this._downloadSize = parseInt(response.headers["content-length"]);
23
- this._statusSuffix = '% of ' + this._humanSize(this._downloadSize);
24
- })
25
- .on("error", (e) => {
26
- this._debug(`got error: ${e}`);
27
- reject(e);
28
- })
29
- .on("data", (data) => {
30
- this._debug(`got ${data.length} bytes`);
31
- this._updateStatus(data);
32
- })
33
- .on("end", () => {
34
- this._clear();
35
- this._rename(resolve, reject, partFile, target);
36
- }).pipe(fs.createWriteStream(partFile));
37
- });
38
- },
39
- abort: function () {
40
- if (this._request) {
41
- self._errored = true;
42
- this._request.abort();
43
- this._clear();
44
- }
45
- },
46
- _updateStatus: function (data) {
47
- if (process.env.SUPPRESS_DOWNLOAD_PROGRESS || process.env.BUILD_NUMBER /* automatically disable at Jenkins CI */) {
48
- return;
49
- }
50
- this._written = this._written || 0;
51
- this._written += data.length;
52
- var perc = Math.round((100 * this._written) / this._downloadSize);
53
- if (perc != this._lastPerc) {
54
- this._writeStatus(perc + this._statusSuffix);
55
- this._lastPerc = perc;
56
- }
57
- },
58
- _writeStatus: function (msg) {
59
- this._clearStatus();
60
- process.stdout.write(msg);
61
- },
62
- _rename: function (resolve, reject, src, dst, attempts) {
63
- try {
64
- this._debug('attempt rename of temp file');
65
- fs.renameSync(src, dst)
66
- this._clearStatus();
67
- this._info(`-> ${dst} download complete!`);
68
- resolve(dst)
69
- } catch (e) {
70
- this._debug('rename error:', e);
71
- if (attempts > 99) {
72
- reject(['Unable to rename "', src, '" to "', ds, '": ', e].join(''));
73
- } else {
74
- setTimeout(()=> {
75
- this._rename(resolve, reject, src, dst, attempts++);
76
- }, 100);
77
- }
78
- }
79
- },
80
- _clearStatus: function () {
81
- process.stdout.write('\r \r');
82
- },
83
- _humanSize: function (size) {
84
- var suffixes = ['b', 'kb', 'mb', 'tb', 'pb'];
85
- for (var i = 0; i < suffixes.length - 1; i++) {
86
- if (size < 1024) {
87
- return size.toFixed(2) + suffixes[i];
88
- }
89
- size /= 1024;
90
- }
91
- return size.toFixed(2) + suffixes[suffixes.length - 1];
92
- },
93
- _clear: function () {
94
- var self = this;
95
- ['_request', '_response', '_downloadSize', '_lastPerc',
96
- '_resolveFunction', '_rejectFunction', '_lastData', '_statusSuffix'
97
- ].forEach(function (prop) {
98
- self[prop] = undefined;
99
- });
100
- },
101
- _alreadyDownloaded: function () {
102
- if (!this.assumeDownloadedIfExistsAndSizeMatches) {
103
- return false;
104
- }
105
- if (!fs.existsSync(this._target)) {
106
- return false;
107
- }
108
- var lstat = fs.lstatSync(this._target);
109
- return lstat.size === this._downloadSize;
110
- }
111
- }
112
-
113
- module.exports = HttpDownloader;
1
+ (function() {
2
+ console.warn("http-downloader is deprecated; this is now a shim to http-client");
3
+ module.exports = requireModule("http-downloader");
4
+ })();
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ (function () {
3
+ // originally, I wanted to use the opn package, now renamed to
4
+ // open, but the author has kindly made it impossible to require
5
+ // from within zarro (I get an error about it being an ESM module);
6
+ // since my requirements are simple, I'll just roll my own.
7
+ const os = require("os"), { ZarroError } = requireModule("zarro-error"), spawn = requireModule("spawn");
8
+ async function open(url) {
9
+ const opener = findOpenerForPlatform();
10
+ await spawn(opener, [url]);
11
+ }
12
+ function findOpenerForPlatform() {
13
+ switch (os.platform()) {
14
+ case "darwin":
15
+ return "open";
16
+ case "netbsd":
17
+ case "freebsd":
18
+ case "linux":
19
+ case "openbsd":
20
+ return "xdg-open";
21
+ case "win32":
22
+ return "start";
23
+ case "cygwin":
24
+ // if we believe: https://stackoverflow.com/a/577698/1697008
25
+ return "cygstart";
26
+ case "aix":
27
+ case "android":
28
+ case "sunos":
29
+ default:
30
+ throw platformNotSupported();
31
+ }
32
+ }
33
+ function platformNotSupported() {
34
+ return new ZarroError(`Platform not supported for opening urls. Please open an issue at https://github.com/fluffynuts/zarro.`);
35
+ }
36
+ module.exports = {
37
+ open
38
+ };
39
+ })();
@@ -1,5 +1,8 @@
1
- module.exports = function(ms) {
2
- return new Promise(resolve => {
3
- setTimeout(resolve, ms);
4
- });
5
- };
1
+ "use strict";
2
+ (function () {
3
+ module.exports = function (ms) {
4
+ return new Promise(resolve => {
5
+ setTimeout(resolve, ms);
6
+ });
7
+ };
8
+ })();
@@ -46,13 +46,20 @@
46
46
  if (!env.resolveFlag(env.DEV_SMTP_OPEN_INTERFACE)) {
47
47
  return;
48
48
  }
49
- const url = generateInterfaceUrlFor(ip, port), open = require("open");
49
+ const url = generateInterfaceUrlFor(ip, port), { open } = requireModule("open");
50
+ await waitForUrlToBecomeAvailable(url);
50
51
  logInfo(`
51
52
  Opening the dev smtp interface in your browser (${url})
52
- To disable this behavor, set env variable ${env.DEV_SMTP_OPEN_INTERFACE}=0
53
+ To disable this behavior, set env variable ${env.DEV_SMTP_OPEN_INTERFACE}=0
53
54
  `.trim());
54
55
  await open(url);
55
56
  }
57
+ async function waitForUrlToBecomeAvailable(url) {
58
+ const sleep = requireModule("sleep"), HttpClient = requireModule("http-client"), httpClient = HttpClient.create();
59
+ do {
60
+ await sleep(500);
61
+ } while (!(await httpClient.exists(url)));
62
+ }
56
63
  const ipMap = {
57
64
  "[::]": "localhost",
58
65
  "127.0.0.1": "localhost"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zarro",
3
- "version": "1.141.5",
3
+ "version": "1.141.8",
4
4
  "description": "Some glue to make gulp easier, perhaps even zero- or close-to-zero-conf",
5
5
  "bin": {
6
6
  "zarro": "./index.js"
@@ -54,7 +54,6 @@
54
54
  "gulp-msbuild": "^0.10.0",
55
55
  "mkdirp": "^1.0.4",
56
56
  "npm-run-all": "^4.1.5",
57
- "open": "^9.1.0",
58
57
  "plugin-error": "^1.0.1",
59
58
  "readline": "^1.3.0",
60
59
  "request": "^2.88.2",
@@ -90,6 +89,7 @@
90
89
  "@types/gulp": "^4.0.8",
91
90
  "@types/jest": "^26.0.20",
92
91
  "@types/node": "^13.13.40",
92
+ "@types/request": "^2.48.8",
93
93
  "@types/rimraf": "^3.0.0",
94
94
  "@types/through2": "^2.0.38",
95
95
  "@types/xml2js": "^0.4.8",
package/types.d.ts CHANGED
@@ -45,6 +45,18 @@ declare global {
45
45
  ): Transform;
46
46
  }
47
47
 
48
+ interface HttpClient {
49
+ download(url: string, target: string): Promise<string>;
50
+ exists(url: string): Promise<boolean>;
51
+ }
52
+
53
+ interface HttpClientModule {
54
+ create(
55
+ infoLogFunction?: (s: string) => void,
56
+ debugLogFunction?: (s: string) => void
57
+ ): HttpClient;
58
+ }
59
+
48
60
  interface GulpWithHelp {
49
61
  task(name: string, callback: GulpCallback): void;
50
62
  task(name: string, help: string, callback: GulpCallback): void;
@@ -217,6 +229,9 @@ declare global {
217
229
  }
218
230
 
219
231
  type GetToolsFolder = (overrideEnv?: Env) => string;
232
+ interface Open {
233
+ open(url: string): Promise<void>;
234
+ }
220
235
 
221
236
  interface Env {
222
237
  resolve(...names: (StringEnvVar | VersionIncrementStrategy)[]): string;