unplugin-https-reverse-proxy 1.0.0-beta.9 → 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/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
@@ -47,17 +85,18 @@ export const unpluginFactory: UnpluginFactory<Options> = options => ({
47
85
  if (config.command !== 'serve')
48
86
  return
49
87
 
50
- if (!isAdmin()) {
51
- consola.warn('please run as administrator')
52
- return
53
- }
54
-
55
88
  const {
56
89
  enable = true,
57
90
  target = '',
58
91
  } = options
92
+
59
93
  if (!enable)
60
94
  return
95
+
96
+ if (!isAdmin()) {
97
+ consola.warn('please run as administrator')
98
+ return
99
+ }
61
100
  if (!target) {
62
101
  consola.fail('please provide target')
63
102
  return
@@ -81,17 +120,19 @@ export const unpluginFactory: UnpluginFactory<Options> = options => ({
81
120
  if (process.env.NODE_ENV !== 'development')
82
121
  return
83
122
 
84
- if (!isAdmin()) {
85
- consola.warn('please run as administrator')
86
- return
87
- }
88
-
89
123
  const {
90
124
  enable = true,
91
125
  target = '',
92
126
  } = options
127
+
93
128
  if (!enable)
94
129
  return
130
+
131
+ if (!isAdmin()) {
132
+ consola.warn('please run as administrator')
133
+ return
134
+ }
135
+
95
136
  if (!target) {
96
137
  consola.fail('please provide target')
97
138
  return
@@ -128,9 +169,9 @@ export const unpluginFactory: UnpluginFactory<Options> = options => ({
128
169
  caddy.run(source, target, {
129
170
  ...options,
130
171
  }).then(() => {
131
- 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()
132
174
 
133
- compiler.hooks.done.tap('unplugin-https-reverse-proxy', () => {
134
175
  consola.success(` ${c.green('➜')} ${c.bold('run caddy reverse proxy success')}: ${colorUrl(`${options.https ? 'https' : 'http'}://${target}`)}`)
135
176
  })
136
177
  }).catch((e) => {
@@ -141,17 +182,19 @@ export const unpluginFactory: UnpluginFactory<Options> = options => ({
141
182
  if (process.env.NODE_ENV !== 'development')
142
183
  return
143
184
 
144
- if (!isAdmin()) {
145
- consola.warn('please run as administrator')
146
- return
147
- }
148
-
149
185
  const {
150
186
  enable = true,
151
187
  target = '',
152
188
  } = options
189
+
153
190
  if (!enable)
154
191
  return
192
+
193
+ if (!isAdmin()) {
194
+ consola.warn('please run as administrator')
195
+ return
196
+ }
197
+
155
198
  if (!target) {
156
199
  consola.fail('please provide target')
157
200
  return
@@ -175,8 +218,8 @@ export const unpluginFactory: UnpluginFactory<Options> = options => ({
175
218
 
176
219
  caddy.run(source, target, {
177
220
  ...options,
178
- }).then(() => {
179
- const colorUrl = (url: string) => c.green(url.replace(/:(\d+)\//, (_, port) => `:${c.bold(port)}/`))
221
+ }).then(async () => {
222
+ await printForwardProxy()
180
223
 
181
224
  consola.success(` ${c.green('➜')} ${c.bold('run caddy reverse proxy success')}: ${colorUrl(`${options.https ? 'https' : 'http'}://${target}`)}`)
182
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
 
@@ -18,17 +18,19 @@ export default defineNuxtModule<ModuleOptions>({
18
18
  if (process.env.NODE_ENV !== 'development')
19
19
  return
20
20
 
21
- if (!isAdmin()) {
22
- consola.warn('please run as administrator')
23
- return
24
- }
25
-
26
21
  const {
27
22
  enable = true,
28
23
  target = '',
29
24
  } = options
25
+
30
26
  if (!enable)
31
27
  return
28
+
29
+ if (!isAdmin()) {
30
+ consola.warn('please run as administrator')
31
+ return
32
+ }
33
+
32
34
  if (!target) {
33
35
  consola.fail('please provide target')
34
36
  return
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
+ }
@@ -1,63 +0,0 @@
1
- var __defProp = Object.defineProperty;
2
- var __getOwnPropSymbols = Object.getOwnPropertySymbols;
3
- var __hasOwnProp = Object.prototype.hasOwnProperty;
4
- var __propIsEnum = Object.prototype.propertyIsEnumerable;
5
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
6
- var __spreadValues = (a, b) => {
7
- for (var prop in b || (b = {}))
8
- if (__hasOwnProp.call(b, prop))
9
- __defNormalProp(a, prop, b[prop]);
10
- if (__getOwnPropSymbols)
11
- for (var prop of __getOwnPropSymbols(b)) {
12
- if (__propIsEnum.call(b, prop))
13
- __defNormalProp(a, prop, b[prop]);
14
- }
15
- return a;
16
- };
17
-
18
- // src/utils.ts
19
- import process from "process";
20
- import path from "path";
21
- import { chmod, readdir, stat } from "fs/promises";
22
- import { execSync } from "child_process";
23
- import { createConsola } from "consola";
24
- var consola = createConsola({
25
- level: 3
26
- }).withTag("reverse-proxy");
27
- async function chmodRecursive(_path, mode) {
28
- await chmod(_path, mode);
29
- if ((await stat(_path)).isDirectory()) {
30
- const children = await readdir(_path);
31
- for (const child of children)
32
- await chmodRecursive(path.join(_path, child), mode);
33
- }
34
- }
35
- function once(fn) {
36
- let called = false;
37
- return (...args) => {
38
- if (called)
39
- return;
40
- called = true;
41
- return fn(...args);
42
- };
43
- }
44
- function isAdmin() {
45
- if (process.platform === "win32") {
46
- try {
47
- execSync("net session", { stdio: "ignore" });
48
- return true;
49
- } catch (e) {
50
- return false;
51
- }
52
- } else {
53
- return process.getuid && process.getuid() === 0;
54
- }
55
- }
56
-
57
- export {
58
- __spreadValues,
59
- consola,
60
- chmodRecursive,
61
- once,
62
- isAdmin
63
- };
@@ -1,19 +0,0 @@
1
- import { existsSync, unlinkSync } from 'node:fs'
2
- import process from 'node:process'
3
- import { consola } from '../src/utils'
4
- import { download } from '../src/caddy'
5
- import { caddyPath } from '../src/caddy/constants'
6
-
7
- async function run() {
8
- try {
9
- if (process.env.UHRP_AUTO_INSTALL_CADDY) {
10
- existsSync(caddyPath) && unlinkSync(caddyPath)
11
- await download()
12
- }
13
- }
14
- catch (e: any) {
15
- consola.error(e.code)
16
- }
17
- }
18
-
19
- run()