windscout 0.3.1 → 0.4.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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/windscout.js +11 -6
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "windscout",
3
- "version": "0.3.1",
3
+ "version": "0.4.0",
4
4
  "description": "Find which Windscribe locations and protocols work from your network, ranked by speed (unofficial)",
5
5
  "type": "module",
6
6
  "bin": {
package/windscout.js CHANGED
@@ -175,6 +175,8 @@ const updateNotice = () => `update available: ${VERSION} → ${update} · run: $
175
175
 
176
176
  const color = (code, s) => (process.env.NO_COLOR || !process.stdout.isTTY ? s : `\x1b[${code}m${s}\x1b[0m`);
177
177
  const bold = (s) => color(1, s), dim = (s) => color(2, s), green = (s) => color(32, s);
178
+ // underline off (24) instead of a full reset, so it nests inside dim/bold
179
+ const under = (s) => (process.env.NO_COLOR || !process.stdout.isTTY ? s : `\x1b[4m${s}\x1b[24m`);
178
180
  const cyan = (s) => color(36, s), yellow = (s) => color(33, s), red = (s) => color(31, s);
179
181
  const fmt = (v, digits) => (v === null || v === undefined ? "-" : v.toFixed(digits));
180
182
  const list = (s) => s.split(",").map((x) => x.trim()).filter(Boolean);
@@ -271,9 +273,12 @@ function matrix(results, protocols, { minWidth = 0, limit = Infinity } = {}) {
271
273
  const reachable = ranked.filter((c) => c.good).length;
272
274
  const rows = ranked.slice(0, limit).map(({ q, rs }) => {
273
275
  const seen = rs.find((r) => r.status === "ok") ?? rs.find((r) => r.location);
276
+ // nickname = exact datacenter; protocols can land on different ones, so list each that connected
277
+ const nicks = [...new Set(rs.filter((r) => r.status === "ok").map((r) => r.location.split(" - ")[1]).filter(Boolean))];
274
278
  return [
275
279
  `${flag(q)} ${countryName(q)}`,
276
280
  seen?.location?.split(" - ")[0] || dim("-"),
281
+ nicks.join(", ") || dim("-"),
277
282
  ...protocols.map((p) => {
278
283
  const r = rs.find((x) => x.protocol === p);
279
284
  return !r ? dim("·") : r.status === "ok" ? green("✓") : red("✗");
@@ -281,13 +286,13 @@ function matrix(results, protocols, { minWidth = 0, limit = Infinity } = {}) {
281
286
  ];
282
287
  });
283
288
  return grid(
284
- [{ title: "Country" }, { title: "City" }, ...protocols.map((p) => ({ title: p, align: "center" }))],
289
+ [{ title: "Country" }, { title: "City" }, { title: "Location" }, ...protocols.map((p) => ({ title: p, align: "center" }))],
285
290
  rows,
286
291
  {
287
292
  caption: bold("Availability"),
288
293
  captionRight: dim(`${reachable}/${ranked.length} countries reachable${ranked.length > limit ? ` · top ${limit}` : ""}`),
289
294
  minWidth,
290
- stretch: 1,
295
+ stretch: 2,
291
296
  },
292
297
  );
293
298
  }
@@ -409,8 +414,8 @@ function pick(saved, timeout) {
409
414
  top = Math.max(0, Math.min(top, list.length - height));
410
415
 
411
416
  const protoLine = PROTOCOLS.map((p, i) =>
412
- `${dim(String(i + 1))} ${protos.has(p) ? green("● " + p) : dim("○ " + p)}`).join(" ");
413
- const speedLine = `${dim("s")} ${speedTest ? green("● speed test") : dim("○ speed test")} ${dim(speedTest
417
+ `${dim(under(String(i + 1)))} ${protos.has(p) ? green("● " + p) : dim("○ " + p)}`).join(" ");
418
+ const speedLine = `${dim(under("s"))} ${speedTest ? green("● speed test") : dim("○ speed test")} ${dim(speedTest
414
419
  ? "ranks by download speed · adds ~15s per working connection"
415
420
  : "off: connect-only, ranks by latency")}`;
416
421
  const search = searching
@@ -425,7 +430,7 @@ function pick(saved, timeout) {
425
430
  return [`${here ? cyan("❯") : " "} ${mark}`, here ? bold(code) : dim(code), here ? bold(cyan(name)) : name];
426
431
  });
427
432
  if (!body.length) body.push([" ", "", dim("no country matches")]);
428
- const buttons = [["start", "▶ Start"], ["all", query ? "All shown" : "All"], ["none", query ? "None shown" : "None"], ["quit", "Quit"]];
433
+ const buttons = [["start", "▶ Start"], ["all", under("A") + (query ? "ll shown" : "ll")], ["none", under("N") + (query ? "one shown" : "one")], ["quit", under("Q") + "uit"]];
429
434
  const buttonLine = buttons.map(([id, label]) => (id === "start" ? bold(cyan(`[ ${label} ]`)) : dim(`[ ${label} ]`))).join(" ");
430
435
 
431
436
  const table = grid([{ title: "" }, { title: "Code" }, { title: "Country" }], body,
@@ -796,7 +801,7 @@ async function main() {
796
801
  if (!tty) throw new Error("no terminal for the picker: pass countries with -c");
797
802
  const saved = loadConfig();
798
803
  if (protocols && saved) saved.protocols = protocols.filter((p) => PROTOCOLS.includes(p));
799
- speedTest = !a["no-speed"] && (saved?.speed ?? true);
804
+ speedTest = !a["no-speed"] && (saved?.speed ?? false); // first run: connect-only
800
805
  const choice = await pick(saved, timeout);
801
806
  if (!choice) return;
802
807
  countries = choice.countries;