unplugin-https-reverse-proxy 1.0.0 → 2.0.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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "unplugin-https-reverse-proxy",
3
3
  "type": "module",
4
- "version": "1.0.0",
4
+ "version": "2.0.0",
5
5
  "description": "",
6
6
  "license": "MIT",
7
7
  "homepage": "https://github.com/zcf0508/unplugin-https-reverse-proxy#readme",
@@ -90,67 +90,70 @@
90
90
  "webpack": "^4 || ^5"
91
91
  },
92
92
  "peerDependenciesMeta": {
93
- "webpack": {
93
+ "@nuxt/kit": {
94
94
  "optional": true
95
95
  },
96
- "@rspack/core": {
96
+ "@nuxt/schema": {
97
97
  "optional": true
98
98
  },
99
99
  "@rsbuild/core": {
100
100
  "optional": true
101
101
  },
102
- "rollup": {
102
+ "@rspack/core": {
103
103
  "optional": true
104
104
  },
105
- "vite": {
105
+ "esbuild": {
106
106
  "optional": true
107
107
  },
108
- "esbuild": {
108
+ "rollup": {
109
109
  "optional": true
110
110
  },
111
- "@nuxt/kit": {
111
+ "vite": {
112
112
  "optional": true
113
113
  },
114
- "@nuxt/schema": {
114
+ "webpack": {
115
115
  "optional": true
116
116
  }
117
117
  },
118
118
  "dependencies": {
119
- "consola": "^3.2.3",
119
+ "consola": "^3.4.2",
120
+ "console-table-printer": "^2.12.1",
120
121
  "dotenv-flow": "^4.1.0",
121
122
  "got-cjs": "^12.5.4",
122
123
  "hostile": "^1.4.0",
123
124
  "http-proxy-agent": "^7.0.2",
124
- "https-proxy-agent": "^7.0.4",
125
+ "https-proxy-agent": "^7.0.6",
125
126
  "ora": "5",
126
- "picocolors": "^1.0.0",
127
- "tsx": "^4.7.1",
128
- "unplugin": "^1.7.1"
127
+ "picocolors": "^1.1.1",
128
+ "qrcode-terminal": "^0.12.0",
129
+ "unplugin": "^2.2.0"
129
130
  },
130
131
  "devDependencies": {
131
- "@antfu/eslint-config": "^0.40.3",
132
- "@nuxt/kit": "^3.10.2",
133
- "@nuxt/schema": "^3.10.2",
134
- "@rsbuild/core": "^0.4.3",
135
- "@rspack/core": "^0.5.4",
132
+ "@antfu/eslint-config": "^4.10.2",
133
+ "@nuxt/kit": "^3.16.1",
134
+ "@nuxt/schema": "^3.16.1",
135
+ "@rsbuild/core": "^0.4.15",
136
+ "@rspack/core": "^0.5.9",
136
137
  "@types/hostile": "^1.3.5",
137
138
  "@types/kill-port": "^2.0.3",
138
139
  "@types/node": "^20.11.19",
139
140
  "@types/proper-lockfile": "^4.1.4",
141
+ "@types/qrcode-terminal": "^0.12.2",
140
142
  "@vue/cli": "^5.0.8",
141
- "bumpp": "^9.3.0",
142
- "chalk": "^5.3.0",
143
+ "bumpp": "^9.11.1",
144
+ "chalk": "^5.4.1",
143
145
  "cross-env": "^7.0.3",
144
- "eslint": "^8.56.0",
145
- "fast-glob": "^3.3.2",
146
- "nodemon": "^3.0.3",
146
+ "eslint": "^9.20.0",
147
+ "fast-glob": "^3.3.3",
148
+ "nodemon": "^3.1.9",
147
149
  "proper-lockfile": "^4.1.2",
148
- "rimraf": "^5.0.5",
150
+ "rimraf": "^5.0.10",
149
151
  "rollup": "^3.29.4",
150
152
  "tsup": "^7.3.0",
151
- "typescript": "^5.3.3",
153
+ "tsx": "^4.19.3",
154
+ "typescript": "^5.8.0",
152
155
  "vite": "^4.5.2",
153
- "vitest": "^2.0.5",
156
+ "vitest": "^3.0.9",
154
157
  "webpack": "^5.90.3"
155
158
  },
156
159
  "scripts": {
@@ -26,12 +26,34 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
26
26
  var import_node_fs3 = require("fs");
27
27
  var import_node_process5 = __toESM(require("process"), 1);
28
28
 
29
+ // src/caddy/index.ts
30
+ var import_node_child_process4 = require("child_process");
31
+ var import_node_fs2 = require("fs");
32
+ var import_promises2 = require("fs/promises");
33
+ var import_node_os3 = require("os");
34
+ var import_node_path3 = require("path");
35
+ var import_node_process4 = __toESM(require("process"), 1);
36
+ var import_got_cjs = require("got-cjs");
37
+ var import_http_proxy_agent = require("http-proxy-agent");
38
+ var import_https_proxy_agent = require("https-proxy-agent");
39
+ var lockfile = __toESM(require("proper-lockfile"), 1);
40
+
41
+ // src/host/index.ts
42
+ var import_node_child_process2 = require("child_process");
43
+ var import_node_fs = require("fs");
44
+ var import_node_process2 = __toESM(require("process"), 1);
45
+ var import_node_util = require("util");
46
+ var import_hostile = __toESM(require("hostile"), 1);
47
+
29
48
  // src/utils.ts
30
- var import_node_process = __toESM(require("process"), 1);
31
- var import_node_path = __toESM(require("path"), 1);
32
- var import_promises = require("fs/promises");
33
49
  var import_node_child_process = require("child_process");
50
+ var import_promises = require("fs/promises");
51
+ var import_node_os = require("os");
52
+ var import_node_path = __toESM(require("path"), 1);
53
+ var import_node_process = __toESM(require("process"), 1);
34
54
  var import_consola = require("consola");
55
+ var import_picocolors = __toESM(require("picocolors"), 1);
56
+ var import_qrcode_terminal = __toESM(require("qrcode-terminal"), 1);
35
57
  var consola = (0, import_consola.createConsola)({
36
58
  level: 3
37
59
  }).withTag("reverse-proxy");
@@ -45,29 +67,13 @@ function once(fn) {
45
67
  };
46
68
  }
47
69
 
48
- // src/caddy/index.ts
49
- var import_node_os2 = require("os");
50
- var import_node_process4 = __toESM(require("process"), 1);
51
- var import_node_fs2 = require("fs");
52
- var import_node_child_process4 = require("child_process");
53
- var import_promises2 = require("fs/promises");
54
- var import_got_cjs = require("got-cjs");
55
- var import_http_proxy_agent = require("http-proxy-agent");
56
- var import_https_proxy_agent = require("https-proxy-agent");
57
- var lockfile = __toESM(require("proper-lockfile"), 1);
58
-
59
70
  // src/host/index.ts
60
- var import_node_process2 = __toESM(require("process"), 1);
61
- var import_node_child_process2 = require("child_process");
62
- var import_node_fs = require("fs");
63
- var import_node_util = require("util");
64
- var import_hostile = __toESM(require("hostile"), 1);
65
71
  var _setHost = (0, import_node_util.promisify)(import_hostile.default.set);
66
72
  var _removeHost = (0, import_node_util.promisify)(import_hostile.default.remove);
67
73
 
68
74
  // src/caddy/constants.ts
75
+ var import_node_os2 = __toESM(require("os"), 1);
69
76
  var import_node_path2 = require("path");
70
- var import_node_os = __toESM(require("os"), 1);
71
77
  var import_node_process3 = __toESM(require("process"), 1);
72
78
  var import_dotenv_flow = __toESM(require("dotenv-flow"), 1);
73
79
  import_dotenv_flow.default.config({
@@ -75,7 +81,7 @@ import_dotenv_flow.default.config({
75
81
  });
76
82
  function resolvePath(path2) {
77
83
  if (path2.startsWith("~"))
78
- return (0, import_node_path2.join)(import_node_os.default.homedir() || "", path2.slice(1));
84
+ return (0, import_node_path2.join)(import_node_os2.default.homedir() || "", path2.slice(1));
79
85
  return path2;
80
86
  }
81
87
  var TEMP_DIR = resolvePath(import_node_process3.default.env.UHRP_CADDY_PATH || import_node_process3.default.env.TEMP || import_node_process3.default.env.TMPDIR || "/tmp");
@@ -194,8 +200,8 @@ var supportList = [
194
200
  ];
195
201
 
196
202
  // src/caddy/utils.ts
197
- var import_node_net = require("net");
198
203
  var import_node_child_process3 = require("child_process");
204
+ var import_node_net = require("net");
199
205
  var import_ora = __toESM(require("ora"), 1);
200
206
  var spinner;
201
207
  function getNumber(number) {
@@ -241,14 +247,14 @@ async function download() {
241
247
  (0, import_node_fs2.chmodSync)(TEMP_DIR, 511);
242
248
  }
243
249
  const file = (0, import_node_fs2.createWriteStream)(caddyPath);
244
- let _platform = (0, import_node_os2.platform)().toString();
250
+ let _platform = (0, import_node_os3.platform)().toString();
245
251
  _platform === "win32" && (_platform = "windows");
246
252
  let _arch = import_node_process4.default.arch.toString();
247
253
  _arch === "x64" && (_arch = "amd64");
248
254
  const support = supportList.find((item) => item.platform === _platform && item.arch === _arch);
249
255
  if (!support)
250
256
  return reject(new Error("not support"));
251
- const dowmloadLink = `https://caddyserver.com/api/download?os=${support.platform}&arch=${support.arch}`;
257
+ const dowmloadLink = `https://caddyserver.com/api/download?os=${support.platform}&arch=${support.arch}&p=github.com%2Fcaddyserver%2Fforwardproxy`;
252
258
  (0, import_node_fs2.existsSync)(caddyPath) && (0, import_node_fs2.unlinkSync)(caddyPath);
253
259
  const httpProxy = import_node_process4.default.env.HTTP_PROXY || import_node_process4.default.env.http_proxy;
254
260
  const httpsProxy = import_node_process4.default.env.HTTPS_PROXY || import_node_process4.default.env.https_proxy;
@@ -1,5 +1,5 @@
1
- import { join } from 'node:path'
2
1
  import os from 'node:os'
2
+ import { join } from 'node:path'
3
3
  import process from 'node:process'
4
4
  import dotenvFlow from 'dotenv-flow'
5
5
 
@@ -7,7 +7,7 @@ dotenvFlow.config({
7
7
  silent: true,
8
8
  })
9
9
 
10
- function resolvePath(path: string) {
10
+ function resolvePath(path: string): string {
11
11
  if (path.startsWith('~'))
12
12
  return join(os.homedir() || '', path.slice(1))
13
13
  return path
@@ -1,18 +1,19 @@
1
- import { platform } from 'node:os'
2
- import process from 'node:process'
3
- import { chmodSync, createWriteStream, existsSync, mkdirSync, unlinkSync, writeFileSync } from 'node:fs'
4
1
  import { spawn } from 'node:child_process'
2
+ import { chmodSync, createWriteStream, existsSync, mkdirSync, unlinkSync, writeFileSync } from 'node:fs'
5
3
  import { readFile, unlink, writeFile } from 'node:fs/promises'
4
+ import { platform } from 'node:os'
5
+ import { join } from 'node:path'
6
+ import process from 'node:process'
6
7
  import { got } from 'got-cjs'
7
8
  import { HttpProxyAgent } from 'http-proxy-agent'
8
9
  import { HttpsProxyAgent } from 'https-proxy-agent'
9
10
  import * as lockfile from 'proper-lockfile'
10
- import { chmodRecursive, consola, once } from '../utils'
11
11
  import { addHost, removeHost } from '../host'
12
- import { TEMP_DIR, caddyFilePath, caddyLockFilePath, caddyPath, supportList } from './constants'
12
+ import { chmodRecursive, consola, once } from '../utils'
13
+ import { caddyFilePath, caddyLockFilePath, caddyPath, supportList, TEMP_DIR } from './constants'
13
14
  import { kill, logProgress, logProgressOver, tryPort } from './utils'
14
15
 
15
- export async function download() {
16
+ export async function download(): Promise<string> {
16
17
  if (await testCaddy())
17
18
  return caddyPath
18
19
 
@@ -38,7 +39,7 @@ export async function download() {
38
39
  if (!support)
39
40
  return reject(new Error('not support'))
40
41
 
41
- const dowmloadLink = `https://caddyserver.com/api/download?os=${support.platform}&arch=${support.arch}`
42
+ const dowmloadLink = `https://caddyserver.com/api/download?os=${support.platform}&arch=${support.arch}&p=github.com%2Fcaddyserver%2Fforwardproxy`
42
43
 
43
44
  existsSync(caddyPath) && unlinkSync(caddyPath)
44
45
 
@@ -75,7 +76,7 @@ export async function download() {
75
76
  })
76
77
  }
77
78
 
78
- function testCaddy() {
79
+ function testCaddy(): Promise<boolean> {
79
80
  return new Promise((resolve, reject) => {
80
81
  if (!existsSync(caddyPath))
81
82
  return resolve(false)
@@ -123,13 +124,13 @@ export class CaddyInstant {
123
124
  this.locked = this.checkLock()
124
125
  }
125
126
 
126
- checkLock() {
127
+ checkLock(): boolean {
127
128
  if (!existsSync(caddyLockFilePath))
128
129
  writeFileSync(caddyLockFilePath, '')
129
130
  return lockfile.checkSync(caddyLockFilePath)
130
131
  }
131
132
 
132
- async getCaddyfile() {
133
+ async getCaddyfile(): Promise<string> {
133
134
  if (!existsSync(caddyFilePath))
134
135
  await this.initCaddyfile()
135
136
 
@@ -137,27 +138,49 @@ export class CaddyInstant {
137
138
  return this.caddyfile
138
139
  }
139
140
 
140
- async initCaddyfile() {
141
+ async initCaddyfile(): Promise<void> {
141
142
  const contet = `
142
143
  {
143
144
  debug
144
145
  auto_https disable_redirects
145
146
  }
146
-
147
+
148
+ :7601 {
149
+ root * "${join(
150
+ process.platform === 'win32'
151
+ ? `${process.env.AppData!}/Caddy`
152
+ : `${process.env.HOME!}/Library/Application Support/Caddy`,
153
+ './pki/authorities/local',
154
+ )}"
155
+ file_server browse
156
+ }
157
+
158
+ # 正向代理配置
159
+ :7600 {
160
+ bind 0.0.0.0
161
+
162
+ forward_proxy {
163
+ hide_ip
164
+ hide_via
165
+ acl {
166
+ allow all
167
+ }
168
+ }
169
+ }
147
170
  `
148
171
  await writeFile(caddyFilePath, contet)
149
172
  this.caddyfile = contet
150
173
  }
151
174
 
152
- async writeCaddyfile() {
175
+ async writeCaddyfile(): Promise<void> {
153
176
  return await writeFile(caddyFilePath, this.caddyfile || '')
154
177
  }
155
178
 
156
- async deleteCaddyfile() {
179
+ async deleteCaddyfile(): Promise<void> {
157
180
  return await unlink(caddyFilePath)
158
181
  }
159
182
 
160
- async init() {
183
+ async init(): Promise<void> {
161
184
  await download()
162
185
  this.inited = true
163
186
  }
@@ -165,9 +188,8 @@ export class CaddyInstant {
165
188
  /**
166
189
  * @param source like `127.0.0.1:8080`
167
190
  * @param target like `test.abc.com`. And if you provide a port ,it will be ignore.
168
- * @returns
169
191
  */
170
- async run(source: string, target: string, options?: Partial<RunOptions>) {
192
+ async run(source: string, target: string, options?: Partial<RunOptions>): Promise<void> {
171
193
  source = source.replace('0.0.0.0', '127.0.0.1')
172
194
  const {
173
195
  restore = true,
@@ -214,7 +236,6 @@ ${target.split(':')[0]}${https ? '' : ':80'} {
214
236
  }
215
237
  }
216
238
  }
217
-
218
239
  `
219
240
 
220
241
  await this.writeCaddyfile()
@@ -230,7 +251,7 @@ ${target.split(':')[0]}${https ? '' : ':80'} {
230
251
  }
231
252
 
232
253
  return new Promise<void>((resolve, reject) => {
233
- const setupCleanup = () => {
254
+ const setupCleanup = (): void => {
234
255
  process.on('SIGINT', async () => {
235
256
  if (this.stoped)
236
257
  return
@@ -340,7 +361,7 @@ ${target.split(':')[0]}${https ? '' : ':80'} {
340
361
  })
341
362
  }
342
363
 
343
- async baseCleanup(restore: boolean = true) {
364
+ async baseCleanup(restore: boolean = true): Promise<void> {
344
365
  try {
345
366
  if (restore && this._source && this._target) {
346
367
  if (await removeHost(this._source.split(':')[0], this._target.split(':')[0]))
@@ -1,5 +1,5 @@
1
- import { createServer } from 'node:net'
2
1
  import { exec } from 'node:child_process'
2
+ import { createServer } from 'node:net'
3
3
  import ora from 'ora'
4
4
  import { consola } from '../utils'
5
5
 
@@ -8,8 +8,8 @@ let spinner: ora.Ora
8
8
  /**
9
9
  * @returns whether the port is in use
10
10
  */
11
- export function tryPort(port: number) {
12
- return new Promise<boolean>((resolve, reject) => {
11
+ export function tryPort(port: number): Promise<boolean> {
12
+ return new Promise<boolean>((resolve, _reject) => {
13
13
  try {
14
14
  const server = createServer().listen(port)
15
15
  server.on('listening', () => {
@@ -23,7 +23,7 @@ export function tryPort(port: number) {
23
23
  server.close()
24
24
  })
25
25
  }
26
- catch (e) {
26
+ catch {
27
27
  resolve(true)
28
28
  }
29
29
  })
@@ -32,9 +32,9 @@ export function tryPort(port: number) {
32
32
  /**
33
33
  * npx free-port :port
34
34
  */
35
- export async function kill(port: number) {
35
+ export async function kill(port: number): Promise<void> {
36
36
  return new Promise<void>((resolve, reject) => {
37
- exec(`npx @maxbo/free-port ${port} -s`, (err, stdout, stderr) => {
37
+ exec(`npx @maxbo/free-port ${port} -s`, (err, stdout, _stderr) => {
38
38
  if (err) {
39
39
  reject(err)
40
40
  }
@@ -46,7 +46,7 @@ export async function kill(port: number) {
46
46
  })
47
47
  }
48
48
 
49
- function getNumber(number: number) {
49
+ function getNumber(number: number): string {
50
50
  if (number <= 0)
51
51
  return '0%'
52
52
  else if (number < 100)
@@ -55,7 +55,7 @@ function getNumber(number: number) {
55
55
  return '100%'
56
56
  }
57
57
 
58
- export function logProgress(percent: number | string) {
58
+ export function logProgress(percent: number | string): void {
59
59
  if (!spinner) {
60
60
  // empty a line before start
61
61
  consola.log('')
@@ -68,7 +68,7 @@ export function logProgress(percent: number | string) {
68
68
  else { spinner.text = `Download Caddy: ${getNumber(Number(percent) * 100)}` }
69
69
  }
70
70
 
71
- export function logProgressOver() {
71
+ export function logProgressOver(): void {
72
72
  if (!spinner) {
73
73
  spinner = ora({
74
74
  text: 'Start Download Caddy: 100%',
package/src/host/index.ts CHANGED
@@ -1,6 +1,6 @@
1
- import process from 'node:process'
2
1
  import { exec } from 'node:child_process'
3
2
  import { chmodSync } from 'node:fs'
3
+ import process from 'node:process'
4
4
  import { promisify } from 'node:util'
5
5
 
6
6
  import hostile from 'hostile'
@@ -9,29 +9,30 @@ import { consola } from '../utils'
9
9
  const _setHost = promisify(hostile.set)
10
10
  const _removeHost = promisify(hostile.remove)
11
11
 
12
- function getPathOfSystemHostsPath() {
12
+ function getPathOfSystemHostsPath(): string {
13
13
  return process.platform === 'win32'
14
14
  ? `${process.env.windir || 'C:\\WINDOWS'}\\system32\\drivers\\etc\\hosts`
15
15
  : '/etc/hosts'
16
16
  }
17
17
 
18
- async function syncHost() {
19
- return new Promise<boolean>((resolve, reject) => {
18
+ async function syncHost(): Promise<boolean> {
19
+ return new Promise<boolean>((resolve, _reject) => {
20
20
  exec(
21
21
  process.platform === 'win32'
22
22
  ? 'ipconfig /flushdns'
23
23
  : 'sudo -E killall -HUP mDNSResponder',
24
- (error, stdout, stderr) => {
24
+ (error, _stdout, _stderr) => {
25
25
  if (error) {
26
26
  consola.error(`exec error: ${error}`)
27
27
  return resolve(false)
28
28
  }
29
29
  return resolve(true)
30
- })
30
+ },
31
+ )
31
32
  })
32
33
  }
33
34
 
34
- export async function addHost(ip: string, host: string) {
35
+ export async function addHost(ip: string, host: string): Promise<boolean> {
35
36
  if (process.platform !== 'win32')
36
37
  chmodSync(getPathOfSystemHostsPath(), 0o777)
37
38
  await _setHost('127.0.0.1', 'localhost')
@@ -41,7 +42,7 @@ export async function addHost(ip: string, host: string) {
41
42
  return await syncHost()
42
43
  }
43
44
 
44
- export async function removeHost(ip: string, host: string) {
45
+ export async function removeHost(ip: string, host: string): Promise<boolean> {
45
46
  if (process.platform !== 'win32')
46
47
  chmodSync(getPathOfSystemHostsPath(), 0o777)
47
48
  await _removeHost(ip, host)
package/src/index.ts CHANGED
@@ -1,11 +1,12 @@
1
- import process from 'node:process'
2
1
  import type { UnpluginFactory } from 'unplugin'
3
- import { createUnplugin } from 'unplugin'
4
2
  import type { ResolvedConfig } from 'vite'
5
- import c from 'picocolors'
6
- import { consola, isAdmin, once } from './utils'
7
3
  import type { Options } from './types'
4
+ import process from 'node:process'
5
+ import { Table } from 'console-table-printer'
6
+ import c from 'picocolors'
7
+ import { createUnplugin } from 'unplugin'
8
8
  import { CaddyInstant } from './caddy'
9
+ import { consola, generateQrcode, getIpv4List, isAdmin, once } from './utils'
9
10
 
10
11
  let config: ResolvedConfig
11
12
 
@@ -13,6 +14,42 @@ let caddy: CaddyInstant
13
14
 
14
15
  const cwd = process.cwd()
15
16
 
17
+ function colorUrl(url: string): string {
18
+ return c.green(url.replace(/:(\d+)\//, (_, port) => `:${c.bold(port)}/`))
19
+ }
20
+
21
+ async function printForwardProxy(): Promise<void> {
22
+ const ipv4List = getIpv4List()
23
+ if (ipv4List.length) {
24
+ const ips = ipv4List.map(ip => c.cyan(ip)).join(', ')
25
+ consola.info(`${c.bold('Mobile device proxy access')}:\n`)
26
+ consola.info('1. Install certificate: scan the QR code and download the \`root.crt\` file,')
27
+ consola.info(' then install it on your mobile device')
28
+
29
+ const ipTable = await Promise.all(
30
+ ipv4List.map(async ip => ({
31
+ target: `http://${ip}:7601`,
32
+ certificate: await generateQrcode(`http://${ip}:7601`),
33
+ })),
34
+ )
35
+
36
+ const table = new Table({
37
+ columns: [
38
+ { name: 'target', alignment: 'left' },
39
+ { name: 'certificate', alignment: 'center', minLen: 28 },
40
+ ],
41
+ })
42
+
43
+ ipTable.forEach((ip) => {
44
+ table.addRow(ip)
45
+ })
46
+
47
+ table.printTable()
48
+
49
+ consola.info(`2. Set proxy on mobile device (Available IPs: ${ips}):${c.bold(7600)}\n\n`)
50
+ }
51
+ }
52
+
16
53
  export const vitePrintUrls = once((
17
54
  options: Options,
18
55
  source: string,
@@ -28,8 +65,9 @@ export const vitePrintUrls = once((
28
65
  caddy.run(source, target, {
29
66
  base,
30
67
  ...options,
31
- }).then(() => {
32
- const colorUrl = (url: string) => c.green(url.replace(/:(\d+)\//, (_, port) => `:${c.bold(port)}/`))
68
+ }).then(async () => {
69
+ await printForwardProxy()
70
+
33
71
  consola.success(` ${c.green('➜')} ${c.bold('run caddy reverse proxy success')}: ${colorUrl(`${options.https ? 'https' : 'http'}://${target}${base}`)}`)
34
72
  }).catch((e) => {
35
73
  throw e
@@ -131,9 +169,9 @@ export const unpluginFactory: UnpluginFactory<Options> = options => ({
131
169
  caddy.run(source, target, {
132
170
  ...options,
133
171
  }).then(() => {
134
- const colorUrl = (url: string) => c.green(url.replace(/:(\d+)\//, (_, port) => `:${c.bold(port)}/`))
172
+ compiler.hooks.done.tap('unplugin-https-reverse-proxy', async () => {
173
+ await printForwardProxy()
135
174
 
136
- compiler.hooks.done.tap('unplugin-https-reverse-proxy', () => {
137
175
  consola.success(` ${c.green('➜')} ${c.bold('run caddy reverse proxy success')}: ${colorUrl(`${options.https ? 'https' : 'http'}://${target}`)}`)
138
176
  })
139
177
  }).catch((e) => {
@@ -180,8 +218,8 @@ export const unpluginFactory: UnpluginFactory<Options> = options => ({
180
218
 
181
219
  caddy.run(source, target, {
182
220
  ...options,
183
- }).then(() => {
184
- const colorUrl = (url: string) => c.green(url.replace(/:(\d+)\//, (_, port) => `:${c.bold(port)}/`))
221
+ }).then(async () => {
222
+ await printForwardProxy()
185
223
 
186
224
  consola.success(` ${c.green('➜')} ${c.bold('run caddy reverse proxy success')}: ${colorUrl(`${options.https ? 'https' : 'http'}://${target}`)}`)
187
225
  }).catch((e) => {
package/src/nuxt.ts CHANGED
@@ -1,9 +1,9 @@
1
+ import type { Options } from './types'
1
2
  import process from 'node:process'
2
3
  import { defineNuxtModule } from '@nuxt/kit'
3
- import type { Options } from './types'
4
- import '@nuxt/schema'
5
- import { consola, isAdmin } from './utils'
6
4
  import { vitePrintUrls } from '.'
5
+ import { consola, isAdmin } from './utils'
6
+ import '@nuxt/schema'
7
7
 
8
8
  export interface ModuleOptions extends Options {
9
9
 
package/src/utils.ts CHANGED
@@ -1,14 +1,17 @@
1
- import process from 'node:process'
2
- import path from 'node:path'
3
- import { chmod, readdir, stat } from 'node:fs/promises'
4
1
  import { execSync } from 'node:child_process'
2
+ import { chmod, readdir, stat } from 'node:fs/promises'
3
+ import { networkInterfaces } from 'node:os'
4
+ import path from 'node:path'
5
+ import process from 'node:process'
5
6
  import { createConsola } from 'consola'
7
+ import c from 'picocolors'
8
+ import qrcode from 'qrcode-terminal'
6
9
 
7
10
  export const consola = createConsola({
8
11
  level: 3,
9
12
  }).withTag('reverse-proxy')
10
13
 
11
- export async function chmodRecursive(_path: string, mode: number) {
14
+ export async function chmodRecursive(_path: string, mode: number): Promise<void> {
12
15
  await chmod(_path, mode)
13
16
  if ((await stat(_path)).isDirectory()) {
14
17
  const children = await readdir(_path)
@@ -27,7 +30,7 @@ export function once<T extends (...args: any[]) => any>(fn: T): (...args: Parame
27
30
  }
28
31
  }
29
32
 
30
- export function isAdmin() {
33
+ export function isAdmin(): boolean {
31
34
  if (process.platform === 'win32') {
32
35
  try {
33
36
  execSync('net session', { stdio: 'ignore' })
@@ -38,6 +41,30 @@ export function isAdmin() {
38
41
  }
39
42
  }
40
43
  else {
41
- return process.getuid && process.getuid() === 0
44
+ return !!(process.getuid && process.getuid() === 0)
42
45
  }
43
46
  }
47
+
48
+ export function getIpv4List(): string[] {
49
+ const interfaces = networkInterfaces()
50
+
51
+ return Object.values(interfaces)
52
+ .flatMap(nInterface => nInterface ?? [])
53
+ .filter(
54
+ detail =>
55
+ detail.address
56
+ && (detail.family === 'IPv4'
57
+ // @ts-expect-error Node 18.0 - 18.3 returns number
58
+ || detail.family === 4),
59
+ )
60
+ .filter(detail => detail.family === 'IPv4' && !detail.internal)
61
+ .map(detail => detail.address)
62
+ }
63
+
64
+ export async function generateQrcode(input: string): Promise<string> {
65
+ return new Promise((resolve) => {
66
+ qrcode.generate(input, { small: true }, (code) => {
67
+ resolve(code.split('\n').map(line => c.bgBlack(c.white(line))).join('\n'))
68
+ })
69
+ })
70
+ }