windscout 0.2.1 → 0.3.0
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.
- package/README.md +2 -0
- package/package.json +1 -1
- package/windscout.js +28 -1
package/README.md
CHANGED
|
@@ -18,6 +18,8 @@ WindScout drives the official `windscribe-cli`: it connects to each country × p
|
|
|
18
18
|
npm install -g windscout # or run once with: npx windscout
|
|
19
19
|
```
|
|
20
20
|
|
|
21
|
+
On startup, WindScout checks npm for a newer version. If there is one, it shows the command to update, both in the picker and after the final report.
|
|
22
|
+
|
|
21
23
|
## Usage
|
|
22
24
|
|
|
23
25
|
Run `windscout` with no arguments to open the interactive picker:
|
package/package.json
CHANGED
package/windscout.js
CHANGED
|
@@ -151,6 +151,26 @@ async function probe(query, protocol, timeout, onStep = () => {}) {
|
|
|
151
151
|
}
|
|
152
152
|
}
|
|
153
153
|
|
|
154
|
+
// ---------- update check ----------
|
|
155
|
+
|
|
156
|
+
const VERSION = JSON.parse(readFileSync(new URL("./package.json", import.meta.url), "utf8")).version;
|
|
157
|
+
let update = null; // newer version on npm, once known
|
|
158
|
+
let updateCheck = Promise.resolve();
|
|
159
|
+
// numeric x.y.z compare; parseInt drops a prerelease suffix ("0-beta" → 0)
|
|
160
|
+
const newer = (a, b) => {
|
|
161
|
+
const x = a.split(".").map((n) => parseInt(n)), y = b.split(".").map((n) => parseInt(n));
|
|
162
|
+
for (let i = 0; i < 3; i++) if (x[i] !== y[i]) return x[i] > y[i];
|
|
163
|
+
return false;
|
|
164
|
+
};
|
|
165
|
+
// best effort: offline or registry down just means no notice
|
|
166
|
+
const checkUpdate = () =>
|
|
167
|
+
fetch("https://registry.npmjs.org/windscout/latest", { signal: AbortSignal.timeout(3000) })
|
|
168
|
+
.then((r) => r.json())
|
|
169
|
+
.then(({ version }) => { if (version && newer(version, VERSION)) update = version; })
|
|
170
|
+
.catch(() => {});
|
|
171
|
+
const updateNotice = () => `update available: ${VERSION} → ${update} · run: ${
|
|
172
|
+
process.env.npm_command === "exec" ? "npx windscout@latest" : "npm install -g windscout@latest"}`;
|
|
173
|
+
|
|
154
174
|
// ---------- formatting ----------
|
|
155
175
|
|
|
156
176
|
const color = (code, s) => (process.env.NO_COLOR || !process.stdout.isTTY ? s : `\x1b[${code}m${s}\x1b[0m`);
|
|
@@ -382,7 +402,7 @@ function pick(saved, timeout) {
|
|
|
382
402
|
const render = () => {
|
|
383
403
|
const rows = out.rows || 24;
|
|
384
404
|
const list = visible();
|
|
385
|
-
const height = Math.max(3, rows - 19);
|
|
405
|
+
const height = Math.max(3, rows - 19 - (update ? 1 : 0));
|
|
386
406
|
cursor = Math.max(0, Math.min(cursor, list.length - 1));
|
|
387
407
|
if (cursor < top) top = cursor;
|
|
388
408
|
if (cursor >= top + height) top = cursor - height + 1;
|
|
@@ -432,6 +452,7 @@ function pick(saved, timeout) {
|
|
|
432
452
|
lines.splice(head.length + table.length + 1, 0, centerIn(buttonLine, width), "");
|
|
433
453
|
if (message) lines.push(centerIn(yellow(message), width));
|
|
434
454
|
lines.push("", centerIn(dim(repoLink), width));
|
|
455
|
+
if (update) lines.push(centerIn(yellow(updateNotice()), width));
|
|
435
456
|
const at = draw(lines);
|
|
436
457
|
|
|
437
458
|
// click map, in screen coordinates
|
|
@@ -458,7 +479,10 @@ function pick(saved, timeout) {
|
|
|
458
479
|
};
|
|
459
480
|
};
|
|
460
481
|
|
|
482
|
+
let closed = false;
|
|
483
|
+
updateCheck.then(() => update && !closed && render()); // the check usually lands after the first draw
|
|
461
484
|
const finish = (value) => {
|
|
485
|
+
closed = true;
|
|
462
486
|
out.off("resize", render);
|
|
463
487
|
input.removeAllListeners("keypress");
|
|
464
488
|
input.removeAllListeners("mouse");
|
|
@@ -747,6 +771,7 @@ async function main() {
|
|
|
747
771
|
},
|
|
748
772
|
});
|
|
749
773
|
if (a.help) return console.log(HELP);
|
|
774
|
+
updateCheck = checkUpdate(); // runs while the app starts and the user picks, before the VPN starts switching
|
|
750
775
|
const timeout = Number(a.timeout);
|
|
751
776
|
if (!(timeout > 0)) throw new Error("--timeout must be a positive number");
|
|
752
777
|
|
|
@@ -776,6 +801,8 @@ async function main() {
|
|
|
776
801
|
const results = await scan(countries, protocols, timeout, tty);
|
|
777
802
|
if (stop) console.log(yellow("interrupted, showing partial results"));
|
|
778
803
|
report(results, protocols, a.all);
|
|
804
|
+
await updateCheck;
|
|
805
|
+
if (update) console.error("\n" + yellow(updateNotice()));
|
|
779
806
|
}
|
|
780
807
|
|
|
781
808
|
main().catch((e) => {
|