unplugin-https-reverse-proxy 1.0.0 → 2.0.1
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 +6 -2
- package/dist/{chunk-2VGRJ3QS.js → chunk-2P7SUCQ3.js} +23 -5
- package/dist/{chunk-KVE7AVSI.js → chunk-DKHKFLLC.js} +89 -23
- package/dist/esbuild.cjs +125 -43
- package/dist/esbuild.js +2 -2
- package/dist/index.cjs +125 -43
- package/dist/index.js +2 -2
- package/dist/nuxt.cjs +116 -42
- package/dist/nuxt.d.cts +1 -1
- package/dist/nuxt.d.ts +1 -1
- package/dist/nuxt.js +6 -2
- package/dist/rollup.cjs +125 -43
- package/dist/rollup.js +2 -2
- package/dist/rspack.cjs +125 -43
- package/dist/rspack.js +2 -2
- package/dist/utils.cjs +24 -4
- package/dist/utils.d.cts +6 -4
- package/dist/utils.d.ts +6 -4
- package/dist/utils.js +5 -1
- package/dist/vite.cjs +125 -43
- package/dist/vite.d.cts +2 -1
- package/dist/vite.d.ts +2 -1
- package/dist/vite.js +2 -2
- package/dist/webpack.cjs +125 -43
- package/dist/webpack.js +2 -2
- package/package.json +29 -26
- package/scripts/postinstall.cjs +30 -24
- package/src/caddy/constants.ts +2 -2
- package/src/caddy/index.ts +41 -20
- package/src/caddy/utils.ts +9 -9
- package/src/host/index.ts +9 -8
- package/src/index.ts +63 -10
- package/src/nuxt.ts +8 -3
- package/src/utils.ts +33 -6
package/src/caddy/index.ts
CHANGED
|
@@ -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 {
|
|
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]))
|
package/src/caddy/utils.ts
CHANGED
|
@@ -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,
|
|
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
|
|
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,
|
|
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,
|
|
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,
|
|
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
|
-
|
|
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
|
|
@@ -64,6 +102,11 @@ export const unpluginFactory: UnpluginFactory<Options> = options => ({
|
|
|
64
102
|
return
|
|
65
103
|
}
|
|
66
104
|
|
|
105
|
+
if (target.match(/^(?:https?)?:\/\//)) {
|
|
106
|
+
consola.fail('target must be a domain')
|
|
107
|
+
return
|
|
108
|
+
}
|
|
109
|
+
|
|
67
110
|
const _printUrls = server.printUrls.bind(server)
|
|
68
111
|
|
|
69
112
|
let source = `localhost:${config.server.port || 5173}`
|
|
@@ -100,6 +143,11 @@ export const unpluginFactory: UnpluginFactory<Options> = options => ({
|
|
|
100
143
|
return
|
|
101
144
|
}
|
|
102
145
|
|
|
146
|
+
if (target.match(/^(?:https?)?:\/\//)) {
|
|
147
|
+
consola.fail('target must be a domain')
|
|
148
|
+
return
|
|
149
|
+
}
|
|
150
|
+
|
|
103
151
|
const devServer = {
|
|
104
152
|
host: 'localhost',
|
|
105
153
|
port: 8080,
|
|
@@ -131,9 +179,9 @@ export const unpluginFactory: UnpluginFactory<Options> = options => ({
|
|
|
131
179
|
caddy.run(source, target, {
|
|
132
180
|
...options,
|
|
133
181
|
}).then(() => {
|
|
134
|
-
|
|
182
|
+
compiler.hooks.done.tap('unplugin-https-reverse-proxy', async () => {
|
|
183
|
+
await printForwardProxy()
|
|
135
184
|
|
|
136
|
-
compiler.hooks.done.tap('unplugin-https-reverse-proxy', () => {
|
|
137
185
|
consola.success(` ${c.green('➜')} ${c.bold('run caddy reverse proxy success')}: ${colorUrl(`${options.https ? 'https' : 'http'}://${target}`)}`)
|
|
138
186
|
})
|
|
139
187
|
}).catch((e) => {
|
|
@@ -162,6 +210,11 @@ export const unpluginFactory: UnpluginFactory<Options> = options => ({
|
|
|
162
210
|
return
|
|
163
211
|
}
|
|
164
212
|
|
|
213
|
+
if (target.match(/^(?:https?)?:\/\//)) {
|
|
214
|
+
consola.fail('target must be a domain')
|
|
215
|
+
return
|
|
216
|
+
}
|
|
217
|
+
|
|
165
218
|
const devServer = {
|
|
166
219
|
host: 'localhost',
|
|
167
220
|
port: 8080,
|
|
@@ -180,8 +233,8 @@ export const unpluginFactory: UnpluginFactory<Options> = options => ({
|
|
|
180
233
|
|
|
181
234
|
caddy.run(source, target, {
|
|
182
235
|
...options,
|
|
183
|
-
}).then(() => {
|
|
184
|
-
|
|
236
|
+
}).then(async () => {
|
|
237
|
+
await printForwardProxy()
|
|
185
238
|
|
|
186
239
|
consola.success(` ${c.green('➜')} ${c.bold('run caddy reverse proxy success')}: ${colorUrl(`${options.https ? 'https' : 'http'}://${target}`)}`)
|
|
187
240
|
}).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
|
|
|
@@ -36,6 +36,11 @@ export default defineNuxtModule<ModuleOptions>({
|
|
|
36
36
|
return
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
+
if (target.match(/^(?:https?)?:\/\//)) {
|
|
40
|
+
consola.fail('target must be a domain')
|
|
41
|
+
return
|
|
42
|
+
}
|
|
43
|
+
|
|
39
44
|
// https://github.com/nuxt/cli/issues/220#issuecomment-1735394141
|
|
40
45
|
_nuxt.hook('listen', (_, listener) => {
|
|
41
46
|
const url = listener.url
|
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
|
+
}
|