@vlandoss/localproxy 0.0.1 → 0.0.2-git-b8d71ee.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 +3 -3
- package/src/commands/clean.ts +6 -1
- package/src/commands/setup.ts +7 -3
- package/src/services/caddy.ts +4 -4
- package/src/services/hosts.ts +27 -8
- package/src/services/shell.ts +2 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vlandoss/localproxy",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.2-git-b8d71ee.0",
|
|
4
4
|
"description": "Simple local development proxy automation",
|
|
5
5
|
"homepage": "https://github.com/variableland/dx/tree/main/packages/localproxy#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -26,8 +26,8 @@
|
|
|
26
26
|
"dependencies": {
|
|
27
27
|
"@inquirer/prompts": "^7.8.4",
|
|
28
28
|
"commander": "13.1.0",
|
|
29
|
-
"@vlandoss/
|
|
30
|
-
"@vlandoss/
|
|
29
|
+
"@vlandoss/loggy": "0.0.4",
|
|
30
|
+
"@vlandoss/clibuddy": "0.0.5"
|
|
31
31
|
},
|
|
32
32
|
"publishConfig": {
|
|
33
33
|
"access": "public"
|
package/src/commands/clean.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { password as passwordPrompt } from "@inquirer/prompts";
|
|
1
2
|
import { createCommand } from "commander";
|
|
2
3
|
import { CaddyService } from "~/services/caddy";
|
|
3
4
|
import { HostsService } from "~/services/hosts";
|
|
@@ -19,8 +20,12 @@ export function createCleanCommand({ caddyfilePath }: Context) {
|
|
|
19
20
|
const localDomains = caddyService.getLocalDomains();
|
|
20
21
|
const hosts = localDomains.map((d) => d.host);
|
|
21
22
|
|
|
23
|
+
const password = await passwordPrompt({
|
|
24
|
+
message: "sudo password to manage hosts",
|
|
25
|
+
});
|
|
26
|
+
|
|
22
27
|
const hostsService = new HostsService(hosts);
|
|
23
|
-
await hostsService.clean(options);
|
|
28
|
+
await hostsService.clean({ ...options, password });
|
|
24
29
|
|
|
25
30
|
logger.success("localproxy clean completed");
|
|
26
31
|
});
|
package/src/commands/setup.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as fs from "node:fs/promises";
|
|
2
2
|
import path from "node:path";
|
|
3
|
-
import { editor } from "@inquirer/prompts";
|
|
3
|
+
import { editor as editorPrompt, password as passwordPrompt } from "@inquirer/prompts";
|
|
4
4
|
import { createCommand } from "commander";
|
|
5
5
|
import { CaddyService } from "~/services/caddy";
|
|
6
6
|
import { HostsService } from "~/services/hosts";
|
|
@@ -65,7 +65,7 @@ export function createSetupCommand({ binDir, installDir, caddyfilePath }: Contex
|
|
|
65
65
|
? await fs.readFile(caddyfilePath, "utf-8")
|
|
66
66
|
: await fs.readFile(exampleCaddyFilePath, "utf-8");
|
|
67
67
|
|
|
68
|
-
const fileContent = await
|
|
68
|
+
const fileContent = await editorPrompt({
|
|
69
69
|
message: "Caddyfile",
|
|
70
70
|
default: defaultContent,
|
|
71
71
|
});
|
|
@@ -80,8 +80,12 @@ export function createSetupCommand({ binDir, installDir, caddyfilePath }: Contex
|
|
|
80
80
|
const localDomains = caddyService.getLocalDomains();
|
|
81
81
|
const hosts = localDomains.map((d) => d.host);
|
|
82
82
|
|
|
83
|
+
const password = await passwordPrompt({
|
|
84
|
+
message: "sudo password to manage hosts",
|
|
85
|
+
});
|
|
86
|
+
|
|
83
87
|
const hostsService = new HostsService(hosts);
|
|
84
|
-
await hostsService.setup(options);
|
|
88
|
+
await hostsService.setup({ ...options, password });
|
|
85
89
|
|
|
86
90
|
logger.success("localproxy setup completed");
|
|
87
91
|
});
|
package/src/services/caddy.ts
CHANGED
|
@@ -56,11 +56,11 @@ export class CaddyService {
|
|
|
56
56
|
const { $ } = this.#shell({ verbose });
|
|
57
57
|
|
|
58
58
|
try {
|
|
59
|
-
|
|
59
|
+
logger.start("Starting Caddy");
|
|
60
60
|
|
|
61
61
|
await $`caddy start -c ${this.#configPath} --pidfile ${this.#pidFilePath} > /dev/null 2>&1`;
|
|
62
62
|
|
|
63
|
-
|
|
63
|
+
logger.success("Caddy started");
|
|
64
64
|
} catch {
|
|
65
65
|
logger.error("Can't start Caddy");
|
|
66
66
|
process.exit(1);
|
|
@@ -71,12 +71,12 @@ export class CaddyService {
|
|
|
71
71
|
const { $ } = this.#shell({ verbose });
|
|
72
72
|
|
|
73
73
|
try {
|
|
74
|
-
|
|
74
|
+
logger.start("Stopping Caddy");
|
|
75
75
|
|
|
76
76
|
await $`caddy stop -c ${this.#configPath}`;
|
|
77
77
|
this.#deleteCaddyPid();
|
|
78
78
|
|
|
79
|
-
|
|
79
|
+
logger.success("Caddy stopped");
|
|
80
80
|
} catch {
|
|
81
81
|
logger.error("Can't stop Caddy");
|
|
82
82
|
process.exit(1);
|
package/src/services/hosts.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { quietShell, silentShell, verboseShell } from "./shell";
|
|
|
3
3
|
|
|
4
4
|
type SetupOptions = {
|
|
5
5
|
verbose: boolean;
|
|
6
|
+
password: string;
|
|
6
7
|
};
|
|
7
8
|
|
|
8
9
|
const debug = logger.subdebug("hosts");
|
|
@@ -18,8 +19,24 @@ export class HostsService {
|
|
|
18
19
|
return verbose ? verboseShell : silentShell;
|
|
19
20
|
}
|
|
20
21
|
|
|
22
|
+
async #auth(password: string) {
|
|
23
|
+
if (!password) {
|
|
24
|
+
throw new Error("Password is required");
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Asking sudo directly in JS is unreliable,
|
|
28
|
+
// so we do it through a shell command
|
|
29
|
+
await silentShell.child({
|
|
30
|
+
stdio: ["ignore", "ignore", "pipe"],
|
|
31
|
+
}).$`echo "${password}" | sudo -S -v`;
|
|
32
|
+
}
|
|
33
|
+
|
|
21
34
|
async setup(options: SetupOptions) {
|
|
22
|
-
await
|
|
35
|
+
await this.#auth(options.password);
|
|
36
|
+
|
|
37
|
+
const { stdout } = await verboseShell.$`sudo hosts backups create`;
|
|
38
|
+
const backupPath = stdout.match(/(\/[^\s]+)/)?.[1];
|
|
39
|
+
debug("Backup created at %s", backupPath);
|
|
23
40
|
|
|
24
41
|
for (const host of this.#hosts) {
|
|
25
42
|
await this.addHost(host, options);
|
|
@@ -27,23 +44,25 @@ export class HostsService {
|
|
|
27
44
|
}
|
|
28
45
|
|
|
29
46
|
async clean(options: SetupOptions) {
|
|
47
|
+
await this.#auth(options.password);
|
|
48
|
+
|
|
30
49
|
for (const host of this.#hosts) {
|
|
31
50
|
await this.removeHost(host, options);
|
|
32
51
|
}
|
|
33
52
|
}
|
|
34
53
|
|
|
35
54
|
async findHost(host: string) {
|
|
36
|
-
const
|
|
37
|
-
debug("Host %s is %s", host,
|
|
38
|
-
return
|
|
55
|
+
const { exitCode } = await quietShell.$`hosts show "${host}"`.nothrow();
|
|
56
|
+
debug("Host %s is %s", host, !exitCode ? "present" : "absent");
|
|
57
|
+
return !exitCode;
|
|
39
58
|
}
|
|
40
59
|
|
|
41
60
|
async addHost(host: string, options: SetupOptions) {
|
|
42
61
|
const { $ } = this.#shell(options);
|
|
43
62
|
|
|
44
|
-
const
|
|
63
|
+
const found = await this.findHost(host);
|
|
45
64
|
|
|
46
|
-
if (!
|
|
65
|
+
if (!found) {
|
|
47
66
|
await $`sudo hosts add 127.0.0.1 ${host}`;
|
|
48
67
|
}
|
|
49
68
|
}
|
|
@@ -51,9 +70,9 @@ export class HostsService {
|
|
|
51
70
|
async removeHost(host: string, options: SetupOptions) {
|
|
52
71
|
const { $ } = this.#shell(options);
|
|
53
72
|
|
|
54
|
-
const
|
|
73
|
+
const found = await this.findHost(host);
|
|
55
74
|
|
|
56
|
-
if (!
|
|
75
|
+
if (!found) {
|
|
57
76
|
await $`sudo hosts remove ${host}`;
|
|
58
77
|
}
|
|
59
78
|
}
|
package/src/services/shell.ts
CHANGED
|
@@ -6,11 +6,11 @@ export const quietShell = createShellService({
|
|
|
6
6
|
});
|
|
7
7
|
|
|
8
8
|
export const silentShell = quietShell.child({
|
|
9
|
-
stdio:
|
|
9
|
+
stdio: "ignore",
|
|
10
10
|
});
|
|
11
11
|
|
|
12
12
|
export const verboseShell = quietShell.child({
|
|
13
13
|
quiet: false,
|
|
14
14
|
verbose: true,
|
|
15
|
-
stdio:
|
|
15
|
+
stdio: "inherit",
|
|
16
16
|
});
|