unplugin-https-reverse-proxy 0.0.22 → 0.0.24

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/dist/webpack.cjs CHANGED
@@ -50,8 +50,8 @@ module.exports = __toCommonJS(webpack_exports);
50
50
  var import_unplugin2 = require("unplugin");
51
51
 
52
52
  // src/index.ts
53
- var import_node_process4 = __toESM(require("process"), 1);
54
- var import_node_fs2 = require("fs");
53
+ var import_node_process5 = __toESM(require("process"), 1);
54
+ var import_node_fs3 = require("fs");
55
55
  var import_unplugin = require("unplugin");
56
56
  var import_picocolors = __toESM(require("picocolors"), 1);
57
57
 
@@ -62,15 +62,6 @@ var import_consola = require("consola");
62
62
  var consola = (0, import_consola.createConsola)({
63
63
  level: 3
64
64
  }).withTag("reverse-proxy");
65
- function once(fn) {
66
- let called = false;
67
- return (...args) => {
68
- if (called)
69
- return;
70
- called = true;
71
- return fn(...args);
72
- };
73
- }
74
65
  function isAdmin() {
75
66
  if (import_node_process.default.platform === "win32") {
76
67
  try {
@@ -86,20 +77,64 @@ function isAdmin() {
86
77
 
87
78
  // src/caddy/index.ts
88
79
  var import_node_os = require("os");
89
- var import_node_process3 = __toESM(require("process"), 1);
90
- var import_node_fs = require("fs");
91
- var import_node_child_process2 = require("child_process");
80
+ var import_node_process4 = __toESM(require("process"), 1);
81
+ var import_node_fs2 = require("fs");
82
+ var import_node_child_process3 = require("child_process");
92
83
  var import_got_cjs = require("got-cjs");
93
84
  var import_http_proxy_agent = require("http-proxy-agent");
94
85
  var import_https_proxy_agent = require("https-proxy-agent");
95
- var import_hosts_so_easy = __toESM(require("hosts-so-easy"), 1);
96
86
  var import_kill_port = __toESM(require("kill-port"), 1);
97
87
 
88
+ // src/host/index.ts
89
+ var import_node_process2 = __toESM(require("process"), 1);
90
+ var import_node_child_process2 = require("child_process");
91
+ var import_node_fs = require("fs");
92
+ var import_hosts_so_easy = __toESM(require("hosts-so-easy"), 1);
93
+ var Hosts = import_hosts_so_easy.default.default || import_hosts_so_easy.default;
94
+ var hostInstance = new Hosts({
95
+ debounceTime: 50,
96
+ hostsFile: getPathOfSystemHostsPath()
97
+ });
98
+ function getPathOfSystemHostsPath() {
99
+ return import_node_process2.default.platform === "win32" ? `${import_node_process2.default.env.windir || "C:\\WINDOWS"}\\system32\\drivers\\etc\\hosts` : "/etc/hosts";
100
+ }
101
+ async function syncHost() {
102
+ return new Promise((resolve, reject) => {
103
+ (0, import_node_child_process2.exec)(
104
+ import_node_process2.default.platform === "win32" ? "ipconfig /flushdns" : "sudo -E killall -HUP mDNSResponder",
105
+ (error, stdout, stderr) => {
106
+ if (error) {
107
+ console.error(`exec error: ${error}`);
108
+ return resolve(false);
109
+ }
110
+ return resolve(true);
111
+ }
112
+ );
113
+ });
114
+ }
115
+ async function addHost(ip, host) {
116
+ if (import_node_process2.default.platform !== "win32")
117
+ (0, import_node_fs.chmodSync)(getPathOfSystemHostsPath(), 511);
118
+ hostInstance.add("127.0.0.1", "localhost");
119
+ hostInstance.add(ip, host);
120
+ await hostInstance.updateFinish();
121
+ return await syncHost();
122
+ }
123
+ async function removeHost(ip, host) {
124
+ if (import_node_process2.default.platform !== "win32")
125
+ (0, import_node_fs.chmodSync)(getPathOfSystemHostsPath(), 511);
126
+ hostInstance.remove(ip, host);
127
+ if (ip === "localhost")
128
+ hostInstance.remove("127.0.0.1", host);
129
+ await hostInstance.updateFinish();
130
+ return await syncHost();
131
+ }
132
+
98
133
  // src/caddy/constants.ts
99
134
  var import_node_path = require("path");
100
- var import_node_process2 = __toESM(require("process"), 1);
101
- var TEMP_DIR = import_node_process2.default.env.TEMP || import_node_process2.default.env.TMPDIR || "/tmp";
102
- var caddyPath = (0, import_node_path.join)(TEMP_DIR, `caddy${import_node_process2.default.platform === "win32" ? ".exe" : ""}`);
135
+ var import_node_process3 = __toESM(require("process"), 1);
136
+ var TEMP_DIR = import_node_process3.default.env.TEMP || import_node_process3.default.env.TMPDIR || "/tmp";
137
+ var caddyPath = (0, import_node_path.join)(TEMP_DIR, `caddy${import_node_process3.default.platform === "win32" ? ".exe" : ""}`);
103
138
  var caddyFilePath = (0, import_node_path.join)(TEMP_DIR, "CADDYFILE");
104
139
  var supportList = [
105
140
  {
@@ -268,23 +303,22 @@ function logProgressOver() {
268
303
  }
269
304
 
270
305
  // src/caddy/index.ts
271
- var Hosts = import_hosts_so_easy.default.default || import_hosts_so_easy.default;
272
306
  async function download() {
273
307
  if (await testCaddy())
274
308
  return caddyPath;
275
309
  return new Promise((resolve, reject) => {
276
- const file = (0, import_node_fs.createWriteStream)(caddyPath);
310
+ const file = (0, import_node_fs2.createWriteStream)(caddyPath);
277
311
  let _platform = (0, import_node_os.platform)().toString();
278
312
  _platform === "win32" && (_platform = "windows");
279
- let _arch = import_node_process3.default.arch.toString();
313
+ let _arch = import_node_process4.default.arch.toString();
280
314
  _arch === "x64" && (_arch = "amd64");
281
315
  const support = supportList.find((item) => item.platform === _platform && item.arch === _arch);
282
316
  if (!support)
283
317
  return reject(new Error("not support"));
284
318
  const dowmloadLink = `https://caddyserver.com/api/download?os=${support.platform}&arch=${support.arch}`;
285
- (0, import_node_fs.existsSync)(caddyPath) && (0, import_node_fs.unlinkSync)(caddyPath);
286
- const httpProxy = import_node_process3.default.env.HTTP_PROXY || import_node_process3.default.env.http_proxy;
287
- const httpsProxy = import_node_process3.default.env.HTTPS_PROXY || import_node_process3.default.env.https_proxy;
319
+ (0, import_node_fs2.existsSync)(caddyPath) && (0, import_node_fs2.unlinkSync)(caddyPath);
320
+ const httpProxy = import_node_process4.default.env.HTTP_PROXY || import_node_process4.default.env.http_proxy;
321
+ const httpsProxy = import_node_process4.default.env.HTTPS_PROXY || import_node_process4.default.env.https_proxy;
288
322
  const httpAgent = httpProxy ? new import_http_proxy_agent.HttpProxyAgent(httpProxy) : void 0;
289
323
  const httpsAgent = httpsProxy ? new import_https_proxy_agent.HttpsProxyAgent(httpsProxy) : void 0;
290
324
  import_got_cjs.got.stream(dowmloadLink, {
@@ -296,9 +330,9 @@ async function download() {
296
330
  logProgress(progress.percent);
297
331
  }).pipe(file).on("finish", () => {
298
332
  logProgressOver();
299
- if (import_node_process3.default.platform === "win32")
333
+ if (import_node_process4.default.platform === "win32")
300
334
  return resolve(caddyPath);
301
- (0, import_node_fs.chmodSync)(caddyPath, 493);
335
+ (0, import_node_fs2.chmodSync)(caddyPath, 493);
302
336
  resolve(caddyPath);
303
337
  }).on("error", (err) => {
304
338
  reject(err);
@@ -307,10 +341,10 @@ async function download() {
307
341
  }
308
342
  function testCaddy() {
309
343
  return new Promise((resolve, reject) => {
310
- if (!(0, import_node_fs.existsSync)(caddyPath))
344
+ if (!(0, import_node_fs2.existsSync)(caddyPath))
311
345
  return resolve(false);
312
- (0, import_node_fs.chmodSync)(caddyPath, 493);
313
- const child = import_node_process3.default.platform === "win32" ? (0, import_node_child_process2.spawn)(caddyPath, []) : (0, import_node_child_process2.spawn)("sudo", ["-E", caddyPath]);
346
+ (0, import_node_fs2.chmodSync)(caddyPath, 493);
347
+ const child = import_node_process4.default.platform === "win32" ? (0, import_node_child_process3.spawn)(caddyPath, []) : (0, import_node_child_process3.spawn)("sudo", ["-E", caddyPath]);
314
348
  child.on("close", () => {
315
349
  return resolve(false);
316
350
  });
@@ -326,7 +360,6 @@ var CaddyInstant = class {
326
360
  constructor() {
327
361
  this.inited = false;
328
362
  this.stoped = false;
329
- this.host = new Hosts();
330
363
  testCaddy().then(() => {
331
364
  this.inited = true;
332
365
  });
@@ -335,51 +368,6 @@ var CaddyInstant = class {
335
368
  await download();
336
369
  this.inited = true;
337
370
  }
338
- async updateHost(ip, host) {
339
- ["localhost", "0.0.0.0"].includes(ip) && (ip = "127.0.0.1");
340
- this.host.add("127.0.0.1", "localhost");
341
- this.host.add(ip, host);
342
- await this.host.updateFinish();
343
- return new Promise((resolve, reject) => {
344
- if (import_node_process3.default.platform === "win32") {
345
- (0, import_node_child_process2.spawn)("ipconfig", ["/flushdns"]).on("error", (err) => {
346
- consola.error(err);
347
- return resolve(false);
348
- }).on("close", () => {
349
- resolve(true);
350
- });
351
- } else {
352
- (0, import_node_child_process2.spawn)("sudo", ["-E", "killall", "-HUP", "mDNSResponder"]).on("error", (err) => {
353
- consola.error(err);
354
- return resolve(false);
355
- }).on("close", () => {
356
- resolve(true);
357
- });
358
- }
359
- });
360
- }
361
- async restoreHost(ip, host) {
362
- ["localhost", "0.0.0.0"].includes(ip) && (ip = "127.0.0.1");
363
- this.host.remove(ip, host);
364
- await this.host.updateFinish();
365
- return new Promise((resolve, reject) => {
366
- if (import_node_process3.default.platform === "win32") {
367
- (0, import_node_child_process2.spawn)("ipconfig", ["/flushdns"]).on("error", (err) => {
368
- consola.error(err);
369
- return resolve(false);
370
- }).on("close", () => {
371
- resolve(true);
372
- });
373
- } else {
374
- (0, import_node_child_process2.spawn)("sudo", ["-E", "killall", "-HUP", "mDNSResponder"]).on("error", (err) => {
375
- consola.error(err);
376
- return resolve(false);
377
- }).on("close", () => {
378
- resolve(true);
379
- });
380
- }
381
- });
382
- }
383
371
  /**
384
372
  * @param source like `127.0.0.1:8080`
385
373
  * @param target like `test.abc.com`. And if you provide a port ,it will be ignore.
@@ -397,16 +385,53 @@ var CaddyInstant = class {
397
385
  await this.init();
398
386
  if (https && await tryPort(443))
399
387
  await (0, import_kill_port.default)(443, "tcp");
400
- if ((import_node_process3.default.platform === "win32" || !https) && await tryPort(80))
388
+ if ((import_node_process4.default.platform === "win32" || !https) && await tryPort(80))
401
389
  await (0, import_kill_port.default)(80, "tcp");
402
- if (!await this.updateHost(source.split(":")[0], target.split(":")[0]))
390
+ if (!await addHost(source.split(":")[0], target.split(":")[0]))
403
391
  throw new Error("update host failed");
404
392
  consola.success("update host success\n");
405
393
  return new Promise((resolve, reject) => {
406
- const child = import_node_process3.default.platform !== "win32" ? (0, import_node_child_process2.spawn)("sudo", ["-E", caddyPath, "reverse-proxy", "--from", `${target.split(":")[0]}${https ? "" : ":80"}`, "--to", `${source}`, "--internal-certs", "--insecure", "--disable-redirects"]) : (0, import_node_child_process2.spawn)(caddyPath, ["reverse-proxy", "--from", `${target.split(":")[0]}`, "--to", `${source}`, "--internal-certs"]);
394
+ const child = import_node_process4.default.platform !== "win32" ? (0, import_node_child_process3.spawn)("sudo", ["-E", caddyPath, "reverse-proxy", "--from", `${target.split(":")[0]}${https ? "" : ":80"}`, "--to", `${source}`, "--internal-certs", "--insecure", "--disable-redirects"]) : (0, import_node_child_process3.spawn)(caddyPath, ["reverse-proxy", "--from", `${target.split(":")[0]}`, "--to", `${source}`, "--internal-certs"]);
407
395
  child.on("error", (err) => {
408
396
  return reject(err);
409
397
  });
398
+ import_node_process4.default.on("SIGINT", async () => {
399
+ if (!restore || this.stoped)
400
+ return;
401
+ try {
402
+ if (await removeHost(source.split(":")[0], target.split(":")[0]))
403
+ consola.success("restore host success\n");
404
+ else
405
+ consola.fail("restore host failed\n");
406
+ } catch (e) {
407
+ consola.error(e);
408
+ consola.fail("restore host failed\n");
409
+ } finally {
410
+ this.stoped = true;
411
+ import_node_process4.default.nextTick(() => {
412
+ import_node_process4.default.exit();
413
+ });
414
+ }
415
+ });
416
+ const originalExit = import_node_process4.default.exit;
417
+ import_node_process4.default.exit = async (code) => {
418
+ if (!restore || this.stoped)
419
+ return originalExit(code);
420
+ try {
421
+ if (await removeHost(source.split(":")[0], target.split(":")[0]))
422
+ consola.success("restore host success\n");
423
+ else
424
+ consola.fail("restore host failed\n");
425
+ } catch (e) {
426
+ consola.error(e);
427
+ consola.fail("restore host failed\n");
428
+ } finally {
429
+ this.stoped = true;
430
+ import_node_process4.default.nextTick(() => {
431
+ originalExit(code);
432
+ });
433
+ }
434
+ };
410
435
  child.stderr.on("data", (data) => {
411
436
  const lines = data.toString().split("\n").map((line) => line.trim());
412
437
  for (const line of lines) {
@@ -419,22 +444,7 @@ var CaddyInstant = class {
419
444
  });
420
445
  child.stdout.on("data", (_data) => {
421
446
  consola.info(_data.toString());
422
- resolve(async (callback) => {
423
- if (!restore || this.stoped)
424
- return;
425
- try {
426
- if (await this.restoreHost(source.split(":")[0], target.split(":")[0]))
427
- consola.success("restore host success\n");
428
- else
429
- consola.fail("restore host failed\n");
430
- } catch (e) {
431
- consola.error(e);
432
- consola.fail("restore host failed\n");
433
- }
434
- this.stoped = true;
435
- child.kill();
436
- callback && callback();
437
- });
447
+ resolve();
438
448
  });
439
449
  });
440
450
  }
@@ -443,55 +453,13 @@ var CaddyInstant = class {
443
453
  // src/index.ts
444
454
  var config;
445
455
  var caddy;
446
- var _stop;
447
456
  var _servce;
448
- function registerExit(clear) {
449
- import_node_process4.default.on("beforeExit", async (_code) => {
450
- await clear();
451
- });
452
- import_node_process4.default.on("uncaughtException", async (err) => {
453
- console.error("An uncaught error occurred!", err.stack);
454
- await clear();
455
- import_node_process4.default.nextTick(() => {
456
- import_node_process4.default.exit(1);
457
- });
458
- });
459
- import_node_process4.default.on("unhandledRejection", async (reason, promise) => {
460
- console.error("Unhandled Rejection at:", promise, "reason:", reason);
461
- await clear();
462
- import_node_process4.default.nextTick(() => {
463
- import_node_process4.default.exit(1);
464
- });
465
- });
466
- import_node_process4.default.once("SIGINT", async () => {
467
- await clear();
468
- import_node_process4.default.exit(0);
469
- });
470
- import_node_process4.default.once("SIGTERM", async () => {
471
- await clear();
472
- import_node_process4.default.exit(0);
473
- });
474
- }
475
457
  var unpluginFactory = (options) => ({
476
458
  name: "unplugin-https-reverse-proxy",
477
459
  enforce: "pre",
478
460
  vite: {
479
461
  configResolved(_config) {
480
462
  config = _config;
481
- registerExit(async () => {
482
- var _a;
483
- try {
484
- if (_servce) {
485
- (_a = _servce.httpServer) == null ? void 0 : _a.close(async () => {
486
- _stop && await _stop();
487
- });
488
- _servce.close();
489
- }
490
- _stop && await _stop();
491
- } catch (e) {
492
- consola.error(e);
493
- }
494
- });
495
463
  },
496
464
  configureServer(server) {
497
465
  if (!isAdmin()) {
@@ -515,10 +483,10 @@ var unpluginFactory = (options) => ({
515
483
  server.printUrls = () => {
516
484
  var _a;
517
485
  _printUrls();
518
- const pwd = import_node_process4.default.cwd();
486
+ const pwd = import_node_process5.default.cwd();
519
487
  const vireCacheDir = `${pwd}/node_modules/.vite`;
520
- if ((0, import_node_fs2.existsSync)(vireCacheDir))
521
- (0, import_node_fs2.chmodSync)(vireCacheDir, 511);
488
+ if ((0, import_node_fs3.existsSync)(vireCacheDir))
489
+ (0, import_node_fs3.chmodSync)(vireCacheDir, 511);
522
490
  let source = `localhost:${config.server.port}`;
523
491
  const url = (_a = server.resolvedUrls) == null ? void 0 : _a.local[0];
524
492
  if (url) {
@@ -532,10 +500,9 @@ var unpluginFactory = (options) => ({
532
500
  caddy = new CaddyInstant();
533
501
  caddy.run(source, target, __spreadValues({
534
502
  base
535
- }, options)).then((stop) => {
503
+ }, options)).then(() => {
536
504
  const colorUrl = (url2) => import_picocolors.default.green(url2.replace(/:(\d+)\//, (_, port) => `:${import_picocolors.default.bold(port)}/`));
537
505
  consola.success(` ${import_picocolors.default.green("\u279C")} ${import_picocolors.default.bold("run caddy reverse proxy success")}: ${colorUrl(`${options.https ? "https" : "http"}://${target}${base}`)}`);
538
- !_stop && (_stop = once(stop));
539
506
  }).catch((e) => {
540
507
  throw e;
541
508
  });
@@ -551,7 +518,7 @@ var unpluginFactory = (options) => ({
551
518
  consola.warn("please run as administrator");
552
519
  return;
553
520
  }
554
- if (import_node_process4.default.env.NODE_ENV !== "development")
521
+ if (import_node_process5.default.env.NODE_ENV !== "development")
555
522
  return;
556
523
  const {
557
524
  enable = true,
@@ -567,37 +534,25 @@ var unpluginFactory = (options) => ({
567
534
  const devServer = __spreadValues(__spreadValues({
568
535
  host: "localhost",
569
536
  port: 8080
570
- }, compiler.options.devServer), import_node_process4.default.VUE_CLI_SERVICE.projectOptions.devServer);
537
+ }, compiler.options.devServer), import_node_process5.default.VUE_CLI_SERVICE.projectOptions.devServer);
571
538
  const source = `${devServer.host}:${devServer.port}`;
572
539
  if (caddy)
573
540
  return;
574
541
  const _close = (_a = compiler.close) == null ? void 0 : _a.bind(compiler);
575
542
  if (_close) {
576
543
  compiler.close = async (callback) => {
577
- try {
578
- _stop && await _stop(() => {
579
- _close && _close(callback);
580
- });
581
- } catch (e) {
582
- consola.error(e);
583
- import_node_process4.default.exit(1);
584
- }
544
+ import_node_process5.default.on("exit", () => {
545
+ _close && _close(callback);
546
+ });
585
547
  };
586
548
  } else {
587
- registerExit(async () => {
588
- try {
589
- _stop && await _stop();
590
- } catch (e) {
591
- consola.error(e);
592
- }
593
- });
549
+ options.https = false;
594
550
  }
595
551
  caddy = new CaddyInstant();
596
- caddy.run(source, target, __spreadValues({}, options)).then((stop) => {
552
+ caddy.run(source, target, __spreadValues({}, options)).then(() => {
597
553
  const colorUrl = (url) => import_picocolors.default.green(url.replace(/:(\d+)\//, (_, port) => `:${import_picocolors.default.bold(port)}/`));
598
554
  compiler.hooks.done.tap("unplugin-https-reverse-proxy", () => {
599
555
  consola.success(` ${import_picocolors.default.green("\u279C")} ${import_picocolors.default.bold("run caddy reverse proxy success")}: ${colorUrl(`${options.https ? "https" : "http"}://${target}`)}`);
600
- !_stop && (_stop = once(stop));
601
556
  });
602
557
  }).catch((e) => {
603
558
  throw e;
package/dist/webpack.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  webpack_default
3
- } from "./chunk-Q7NSASV3.js";
4
- import "./chunk-BTWCTT26.js";
5
- import "./chunk-NNO3ZUSU.js";
3
+ } from "./chunk-W4RHTMNZ.js";
4
+ import "./chunk-TVCN6ESH.js";
5
+ import "./chunk-3RTK3FSZ.js";
6
6
  export {
7
7
  webpack_default as default
8
8
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "unplugin-https-reverse-proxy",
3
3
  "type": "module",
4
- "version": "0.0.22",
4
+ "version": "0.0.24",
5
5
  "packageManager": "pnpm@8.6.12",
6
6
  "description": "",
7
7
  "license": "MIT",
@@ -5,16 +5,12 @@ import { spawn } from 'node:child_process'
5
5
  import { got } from 'got-cjs'
6
6
  import { HttpProxyAgent } from 'http-proxy-agent'
7
7
  import { HttpsProxyAgent } from 'https-proxy-agent'
8
-
9
- // @ts-expect-error no type
10
- import _Hosts from 'hosts-so-easy'
11
8
  import kill from 'kill-port'
12
9
  import { consola } from '../utils'
10
+ import { addHost, removeHost } from '../host'
13
11
  import { caddyPath, supportList } from './constants'
14
12
  import { logProgress, logProgressOver, tryPort } from './utils'
15
13
 
16
- const Hosts = _Hosts.default || _Hosts
17
-
18
14
  export async function download() {
19
15
  if (await testCaddy())
20
16
  return caddyPath
@@ -95,10 +91,8 @@ interface RunOptions {
95
91
  export class CaddyInstant {
96
92
  private inited = false
97
93
  private stoped = false
98
- private host: typeof Hosts
99
94
 
100
95
  constructor() {
101
- this.host = new Hosts()
102
96
  testCaddy().then(() => {
103
97
  this.inited = true
104
98
  })
@@ -109,55 +103,6 @@ export class CaddyInstant {
109
103
  this.inited = true
110
104
  }
111
105
 
112
- private async updateHost(ip: string, host: string) {
113
- ['localhost', '0.0.0.0'].includes(ip) && (ip = '127.0.0.1')
114
- this.host.add('127.0.0.1', 'localhost')
115
- this.host.add(ip, host)
116
- await this.host.updateFinish()
117
- return new Promise<boolean>((resolve, reject) => {
118
- if (process.platform === 'win32') {
119
- spawn('ipconfig', ['/flushdns']).on('error', (err) => {
120
- consola.error(err)
121
- return resolve(false)
122
- }).on('close', () => {
123
- resolve(true)
124
- })
125
- }
126
- else {
127
- spawn('sudo', ['-E', 'killall', '-HUP', 'mDNSResponder']).on('error', (err) => {
128
- consola.error(err)
129
- return resolve(false)
130
- }).on('close', () => {
131
- resolve(true)
132
- })
133
- }
134
- })
135
- }
136
-
137
- private async restoreHost(ip: string, host: string) {
138
- ['localhost', '0.0.0.0'].includes(ip) && (ip = '127.0.0.1')
139
- this.host.remove(ip, host)
140
- await this.host.updateFinish()
141
- return new Promise<boolean>((resolve, reject) => {
142
- if (process.platform === 'win32') {
143
- spawn('ipconfig', ['/flushdns']).on('error', (err) => {
144
- consola.error(err)
145
- return resolve(false)
146
- }).on('close', () => {
147
- resolve(true)
148
- })
149
- }
150
- else {
151
- spawn('sudo', ['-E', 'killall', '-HUP', 'mDNSResponder']).on('error', (err) => {
152
- consola.error(err)
153
- return resolve(false)
154
- }).on('close', () => {
155
- resolve(true)
156
- })
157
- }
158
- })
159
- }
160
-
161
106
  /**
162
107
  * @param source like `127.0.0.1:8080`
163
108
  * @param target like `test.abc.com`. And if you provide a port ,it will be ignore.
@@ -180,11 +125,11 @@ export class CaddyInstant {
180
125
  if ((process.platform === 'win32' || !https) && await tryPort(80))
181
126
  await kill(80, 'tcp')
182
127
 
183
- if (!await this.updateHost(source.split(':')[0], target.split(':')[0]))
128
+ if (!await addHost(source.split(':')[0], target.split(':')[0]))
184
129
  throw new Error('update host failed')
185
130
  consola.success('update host success\n')
186
131
 
187
- return new Promise<(callback?: () => any) => Promise<void>>((resolve, reject) => {
132
+ return new Promise<void>((resolve, reject) => {
188
133
  // caddy reverse-proxy --from target --to source --internal-certs
189
134
  const child = process.platform !== 'win32'
190
135
  ? spawn('sudo', ['-E', caddyPath, 'reverse-proxy', '--from', `${target.split(':')[0]}${https ? '' : ':80'}`, '--to', `${source}`, '--internal-certs', '--insecure', '--disable-redirects'])
@@ -194,6 +139,55 @@ export class CaddyInstant {
194
139
  return reject(err)
195
140
  })
196
141
 
142
+ process.on('SIGINT', async () => {
143
+ if (!restore || this.stoped)
144
+ return
145
+
146
+ try {
147
+ if (await removeHost(source.split(':')[0], target.split(':')[0]))
148
+ consola.success('restore host success\n')
149
+
150
+ else
151
+ consola.fail('restore host failed\n')
152
+ }
153
+ catch (e) {
154
+ consola.error(e)
155
+ consola.fail('restore host failed\n')
156
+ }
157
+ finally {
158
+ this.stoped = true
159
+ process.nextTick(() => {
160
+ process.exit()
161
+ })
162
+ }
163
+ })
164
+
165
+ const originalExit = process.exit
166
+
167
+ // @ts-expect-error override
168
+ process.exit = async (code?: number) => {
169
+ if (!restore || this.stoped)
170
+ return originalExit(code)
171
+
172
+ try {
173
+ if (await removeHost(source.split(':')[0], target.split(':')[0]))
174
+ consola.success('restore host success\n')
175
+
176
+ else
177
+ consola.fail('restore host failed\n')
178
+ }
179
+ catch (e) {
180
+ consola.error(e)
181
+ consola.fail('restore host failed\n')
182
+ }
183
+ finally {
184
+ this.stoped = true
185
+ process.nextTick(() => {
186
+ originalExit(code)
187
+ })
188
+ }
189
+ }
190
+
197
191
  child.stderr.on('data', (data) => {
198
192
  const lines = (data.toString() as string).split('\n').map(line => line.trim())
199
193
  for (const line of lines) {
@@ -210,26 +204,7 @@ export class CaddyInstant {
210
204
 
211
205
  child.stdout.on('data', (_data) => {
212
206
  consola.info(_data.toString())
213
- resolve(async (callback?: () => any) => {
214
- if (!restore || this.stoped)
215
- return
216
-
217
- try {
218
- if (await this.restoreHost(source.split(':')[0], target.split(':')[0]))
219
- consola.success('restore host success\n')
220
-
221
- else
222
- consola.fail('restore host failed\n')
223
- }
224
- catch (e) {
225
- consola.error(e)
226
- consola.fail('restore host failed\n')
227
- }
228
-
229
- this.stoped = true
230
- child.kill()
231
- callback && callback()
232
- })
207
+ resolve()
233
208
  })
234
209
  })
235
210
  }
@@ -0,0 +1,54 @@
1
+ import process from 'node:process'
2
+ import { exec } from 'node:child_process'
3
+ import { chmodSync } from 'node:fs'
4
+
5
+ // @ts-expect-error no type
6
+ import _Hosts from 'hosts-so-easy'
7
+
8
+ const Hosts = _Hosts.default || _Hosts
9
+
10
+ const hostInstance = new Hosts({
11
+ debounceTime: 50,
12
+ hostsFile: getPathOfSystemHostsPath(),
13
+ })
14
+
15
+ function getPathOfSystemHostsPath() {
16
+ return process.platform === 'win32'
17
+ ? `${process.env.windir || 'C:\\WINDOWS'}\\system32\\drivers\\etc\\hosts`
18
+ : '/etc/hosts'
19
+ }
20
+
21
+ async function syncHost() {
22
+ return new Promise<boolean>((resolve, reject) => {
23
+ exec(
24
+ process.platform === 'win32'
25
+ ? 'ipconfig /flushdns'
26
+ : 'sudo -E killall -HUP mDNSResponder',
27
+ (error, stdout, stderr) => {
28
+ if (error) {
29
+ console.error(`exec error: ${error}`)
30
+ return resolve(false)
31
+ }
32
+ return resolve(true)
33
+ })
34
+ })
35
+ }
36
+
37
+ export async function addHost(ip: string, host: string) {
38
+ if (process.platform !== 'win32')
39
+ chmodSync(getPathOfSystemHostsPath(), 0o777)
40
+ hostInstance.add('127.0.0.1', 'localhost')
41
+ hostInstance.add(ip, host)
42
+ await hostInstance.updateFinish()
43
+ return await syncHost()
44
+ }
45
+
46
+ export async function removeHost(ip: string, host: string) {
47
+ if (process.platform !== 'win32')
48
+ chmodSync(getPathOfSystemHostsPath(), 0o777)
49
+ hostInstance.remove(ip, host)
50
+ if (ip === 'localhost')
51
+ hostInstance.remove('127.0.0.1', host)
52
+ await hostInstance.updateFinish()
53
+ return await syncHost()
54
+ }