unplugin-https-reverse-proxy 1.0.0-beta.16 → 1.0.0-beta.18

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.
@@ -6,12 +6,11 @@ import { readFile, unlink, writeFile } from 'node:fs/promises'
6
6
  import { got } from 'got-cjs'
7
7
  import { HttpProxyAgent } from 'http-proxy-agent'
8
8
  import { HttpsProxyAgent } from 'https-proxy-agent'
9
- import kill from 'kill-port'
10
9
  import * as lockfile from 'proper-lockfile'
11
10
  import { chmodRecursive, consola, once } from '../utils'
12
11
  import { addHost, removeHost } from '../host'
13
12
  import { TEMP_DIR, caddyFilePath, caddyLockFilePath, caddyPath, supportList } from './constants'
14
- import { logProgress, logProgressOver, tryPort } from './utils'
13
+ import { kill, logProgress, logProgressOver, tryPort } from './utils'
15
14
 
16
15
  export async function download() {
17
16
  if (await testCaddy())
@@ -109,6 +108,11 @@ export class CaddyInstant {
109
108
  private locked = false
110
109
  private caddyfile: string | undefined
111
110
 
111
+ private _caddyChild: ReturnType<typeof spawn> | undefined
112
+
113
+ private _source: string | undefined
114
+ private _target: string | undefined
115
+
112
116
  constructor() {
113
117
  testCaddy().then(async () => {
114
118
  await this.getCaddyfile()
@@ -172,6 +176,9 @@ export class CaddyInstant {
172
176
  https = false,
173
177
  } = options || {}
174
178
 
179
+ this._source = source
180
+ this._target = target
181
+
175
182
  if (!this.inited)
176
183
  await this.init()
177
184
 
@@ -197,29 +204,21 @@ ${target.split(':')[0]}${https ? '' : ':80'} {
197
204
 
198
205
  if (!this.locked) {
199
206
  if (await tryPort(443))
200
- await kill(443, 'tcp')
207
+ await kill(443)
201
208
  if ((process.platform === 'win32' || !https) && await tryPort(80))
202
- await kill(80, 'tcp')
209
+ await kill(80)
203
210
  }
204
211
 
205
212
  return new Promise<void>((resolve, reject) => {
206
213
  const setupCleanup = () => {
207
214
  process.on('SIGINT', async () => {
208
- if (!restore || this.stoped)
215
+ if (this.stoped)
209
216
  return
210
217
 
211
- await this.baseCleanup()
218
+ process.stdin.resume()
212
219
 
213
220
  try {
214
- if (await removeHost(source.split(':')[0], target.split(':')[0]))
215
- consola.success('Restore host success.\n')
216
-
217
- else
218
- consola.fail('Restore host failed.\n')
219
- }
220
- catch (e) {
221
- consola.error(e)
222
- consola.fail('Restore host failed.\n')
221
+ await this.baseCleanup(restore)
223
222
  }
224
223
  finally {
225
224
  this.stoped = true
@@ -235,36 +234,29 @@ ${target.split(':')[0]}${https ? '' : ':80'} {
235
234
  process.exit = async (code?: number) => {
236
235
  const port = Number(source.split(':')[1])
237
236
  if (!Number.isNaN(port) && await tryPort(port))
238
- await kill(port, 'tcp')
237
+ await kill(port)
239
238
 
240
239
  // fix `Error: EPERM: operation not permitted`
241
240
  const pwd = process.cwd()
242
241
  const viteCacheDir = `${pwd}/node_modules/.vite`
243
242
  if (existsSync(viteCacheDir))
244
- chmodRecursive(viteCacheDir, 0o777)
243
+ await chmodRecursive(viteCacheDir, 0o777).catch(() => { })
245
244
  const nuxtCacheDir = `${pwd}/.nuxt`
246
245
  if (existsSync(nuxtCacheDir))
247
- await chmodRecursive(nuxtCacheDir, 0o777)
246
+ await chmodRecursive(nuxtCacheDir, 0o777).catch(() => { })
248
247
  const webpackCacheDir = `${pwd}/node_modules/.cache`
249
248
  if (existsSync(webpackCacheDir))
250
- chmodRecursive(webpackCacheDir, 0o777)
249
+ await chmodRecursive(webpackCacheDir, 0o777).catch(() => { })
251
250
 
252
- if (!restore || this.stoped)
251
+ if (this.stoped)
253
252
  return originalExit(code)
254
253
 
255
- await this.baseCleanup()
254
+ process.stdin.resume()
256
255
 
257
256
  try {
258
- if (await removeHost(source.split(':')[0], target.split(':')[0]))
259
- consola.success('Restore host success.\n')
260
-
261
- else
262
- consola.fail('Restore host failed.\n')
263
- }
264
- catch (e) {
265
- consola.error(e)
266
- consola.fail('Restore host failed.\n')
257
+ await this.baseCleanup()
267
258
  }
259
+
268
260
  finally {
269
261
  this.stoped = true
270
262
  process.nextTick(() => {
@@ -275,17 +267,17 @@ ${target.split(':')[0]}${https ? '' : ':80'} {
275
267
  }
276
268
 
277
269
  if (!this.locked) {
278
- const child = process.platform !== 'win32'
270
+ this._caddyChild = process.platform !== 'win32'
279
271
  ? spawn('sudo', ['-E', caddyPath, 'run', '--config', caddyFilePath, '--watch'])
280
272
  : spawn(caddyPath, ['run', '--config', caddyFilePath, '--watch'])
281
273
 
282
274
  lockfile.lockSync(caddyLockFilePath)
283
275
 
284
- child.on('error', (err) => {
276
+ this._caddyChild!.on('error', (err) => {
285
277
  return reject(err)
286
278
  })
287
279
 
288
- child.stderr.on('data', (data) => {
280
+ this._caddyChild!.stderr?.on('data', (data) => {
289
281
  const lines = (data.toString() as string).split('\n').map(line => line.trim())
290
282
  for (const line of lines) {
291
283
  // caddy log
@@ -304,7 +296,7 @@ ${target.split(':')[0]}${https ? '' : ':80'} {
304
296
  }
305
297
  })
306
298
 
307
- child.stdout.on('data', (_data) => {
299
+ this._caddyChild!.stdout?.on('data', (_data) => {
308
300
  consola.info(_data.toString())
309
301
  resolve()
310
302
  })
@@ -321,15 +313,29 @@ ${target.split(':')[0]}${https ? '' : ':80'} {
321
313
  })
322
314
  }
323
315
 
324
- async baseCleanup() {
325
- if (!this.locked) {
316
+ async baseCleanup(restore: boolean = true) {
317
+ try {
318
+ if (restore && this._source && this._target) {
319
+ if (await removeHost(this._source.split(':')[0], this._target.split(':')[0]))
320
+ consola.success('Restore host success.\n')
321
+
322
+ else
323
+ consola.fail('Restore host failed.\n')
324
+ }
325
+ }
326
+ catch (e) {
327
+ consola.error(e)
328
+ consola.fail('Restore host failed.\n')
329
+ }
330
+ if (!this.locked && !this.stoped) {
331
+ this._caddyChild?.kill()
326
332
  try {
327
- await lockfile.unlock(caddyLockFilePath)
328
- await unlink(caddyFilePath)
329
- await unlink(caddyLockFilePath)
333
+ await lockfile.unlock(caddyLockFilePath).catch(() => { })
334
+ await unlink(caddyFilePath).catch(() => { })
335
+ await unlink(caddyLockFilePath).catch(() => { })
330
336
  }
331
337
  catch (e) {
332
- // consola.error(e)
338
+ consola.error(e)
333
339
  }
334
340
  }
335
341
  }
@@ -1,4 +1,5 @@
1
1
  import { createServer } from 'node:net'
2
+ import { exec } from 'node:child_process'
2
3
  import ora from 'ora'
3
4
  import { consola } from '../utils'
4
5
 
@@ -28,6 +29,23 @@ export function tryPort(port: number) {
28
29
  })
29
30
  }
30
31
 
32
+ /**
33
+ * npx free-port :port
34
+ */
35
+ export async function kill(port: number) {
36
+ return new Promise<void>((resolve, reject) => {
37
+ exec(`npx @maxbo/free-port ${port} -s`, (err, stdout, stderr) => {
38
+ if (err) {
39
+ reject(err)
40
+ }
41
+ else {
42
+ consola.log(stdout)
43
+ resolve()
44
+ }
45
+ })
46
+ })
47
+ }
48
+
31
49
  function getNumber(number: number) {
32
50
  if (number <= 0)
33
51
  return '0%'
package/src/host/index.ts CHANGED
@@ -1,17 +1,13 @@
1
1
  import process from 'node:process'
2
2
  import { exec } from 'node:child_process'
3
3
  import { chmodSync } from 'node:fs'
4
+ import { promisify } from 'node:util'
4
5
 
5
- // @ts-expect-error no type
6
- import _Hosts from 'hosts-so-easy'
6
+ import hostile from 'hostile'
7
7
  import { consola } from '../utils'
8
8
 
9
- const Hosts = _Hosts.default || _Hosts
10
-
11
- const hostInstance = new Hosts({
12
- debounceTime: 50,
13
- hostsFile: getPathOfSystemHostsPath(),
14
- })
9
+ const _setHost = promisify(hostile.set)
10
+ const _removeHost = promisify(hostile.remove)
15
11
 
16
12
  function getPathOfSystemHostsPath() {
17
13
  return process.platform === 'win32'
@@ -38,20 +34,18 @@ async function syncHost() {
38
34
  export async function addHost(ip: string, host: string) {
39
35
  if (process.platform !== 'win32')
40
36
  chmodSync(getPathOfSystemHostsPath(), 0o777)
41
- hostInstance.add('127.0.0.1', 'localhost')
42
- hostInstance.add(ip, host)
37
+ await _setHost('127.0.0.1', 'localhost')
38
+ await _setHost(ip, host)
43
39
  if (ip === 'localhost')
44
- hostInstance.add('127.0.0.1', host)
45
- await hostInstance.updateFinish()
40
+ await _setHost('127.0.0.1', host)
46
41
  return await syncHost()
47
42
  }
48
43
 
49
44
  export async function removeHost(ip: string, host: string) {
50
45
  if (process.platform !== 'win32')
51
46
  chmodSync(getPathOfSystemHostsPath(), 0o777)
52
- hostInstance.remove(ip, host)
47
+ await _removeHost(ip, host)
53
48
  if (ip === 'localhost')
54
- hostInstance.remove('127.0.0.1', host)
55
- await hostInstance.updateFinish()
49
+ await _removeHost('127.0.0.1', host)
56
50
  return await syncHost()
57
51
  }