frontend: remove utils commons
Kim committed
Mar 23, 2026 at 14:49 UTC
99acf32acab1f7b2df664f3c6a0f68a86474f976
8 files changed
+16
-28
extensions/vscode/README.md
+2
-3
@@ -4,7 +4,7 @@ Expose your local service to the internet via a [Portal](https://github.com/gosu
4
5
## Features
6
7
-- `Portal: Start Tunnel` prompts only for the local host:port, then starts the tunnel with a stable generated name plus configured relay URLs or the default public registry
7
+- `Portal: Start Tunnel` prompts only for the local host:port, then starts the tunnel with configured relay URLs or the default public registry
8
- `Portal: Start Tunnel (Advanced)` prompts for host, optional service name, relay source, and optional thumbnail
9
- `Portal: Stop Tunnel` stops the active tunnel terminal
10
- Persisted settings for relay URLs, default local host, and default service name
@@ -22,7 +22,7 @@ Expose your local service to the internet via a [Portal](https://github.com/gosu
22
|---|---|---|
23
| `portal.relayUrls` | `[]` | Relay server URLs (`https://` only). If empty, the extension uses `https://raw.githubusercontent.com/gosuda/portal/main/registry.json`. |
24
| `portal.defaultHost` | `"localhost:3000"` | Default local host:port shown by `Portal: Start Tunnel`. |
25
-| `portal.defaultName` | `""` | Default tunnel service name suggestion. If empty, Portal generates a stable default name from the local host and machine seed. |
25
+| `portal.defaultName` | `""` | Default tunnel service name suggestion. If empty, the extension omits `--name`. |
26
27
Example `settings.json`:
28
@@ -70,5 +70,4 @@ If you want Linux behavior from WSL, open the folder with `Remote - WSL` first s
70
- Enforce `https://` relay URLs
71
- Prompt only for the local host in `Portal: Start Tunnel`
72
- Add `Portal: Start Tunnel (Advanced)` for host, name, relay, and thumbnail overrides
73
-- Generate a stable default service name in the extension when the name is empty
73
- Use the installed Portal binary path after installer execution
extensions/vscode/package.json
+1
-1
@@ -49,7 +49,7 @@
49
"portal.defaultName": {
50
"type": "string",
51
"default": "",
52
- "description": "Default tunnel service name suggestion. Leave empty to let Portal generate a stable default name."
52
+ "description": "Default tunnel service name suggestion. Leave empty to omit --name."
53
}
54
}
55
}
extensions/vscode/src/command.ts
+5
-5
@@ -1,5 +1,4 @@
1
import * as os from "os";
2
-import { resolveExposeName } from "../../../utils/exposeName";
2
3
export type ShellTarget = "unix" | "windows";
4
@@ -8,7 +7,6 @@ export const defaultRelayRegistryURL = "https://raw.githubusercontent.com/gosuda
7
export interface TunnelCommandOptions {
8
host: string;
9
name: string;
11
- nameSeed: string;
10
relayList: string;
11
relayUrl: string;
12
thumbnail: string;
@@ -37,13 +35,15 @@ export function shellTargetForPlatform(platform = os.platform()): ShellTarget {
35
}
36
37
export function buildCommand(opts: TunnelCommandOptions, target = shellTargetForPlatform()): string {
40
- const { host, name, nameSeed, relayList, relayUrl, thumbnail, isLocal } = opts;
38
+ const { host, name, relayList, relayUrl, thumbnail, isLocal } = opts;
39
const installShellUrl = `${relayUrl}/install.sh`;
40
const installPowerShellUrl = `${relayUrl}/install.ps1`;
41
const exposeArgs: string[] = [];
44
- const resolvedName = resolveExposeName(name, host, nameSeed);
42
46
- exposeArgs.push(`--name ${formatToken(resolvedName, target)}`);
43
+ const trimmedName = name.trim();
44
+ if (trimmedName) {
45
+ exposeArgs.push(`--name ${formatToken(trimmedName, target)}`);
46
+ }
47
if (relayList.trim()) {
48
exposeArgs.push(`--relays ${formatToken(relayList, target)}`);
49
}
extensions/vscode/src/extension.ts
+1
-2
@@ -77,7 +77,6 @@ function runTunnelCommand(args: {
77
const command = buildCommand({
78
host: args.host,
79
name: args.name,
80
- nameSeed: vscode.env.machineId,
80
relayList: args.relaySelection.relayUrls.join(","),
81
relayUrl: args.relaySelection.installRelayUrl,
82
thumbnail: args.thumbnail,
@@ -118,7 +117,7 @@ async function promptName(): Promise<string | undefined> {
117
const defaultName = config.get<string>("defaultName") ?? "";
118
return vscode.window.showInputBox({
119
title: "Portal: Service Name",
121
- prompt: "Optional public hostname prefix. Leave empty to auto-generate a stable default name.",
120
+ prompt: "Optional public hostname prefix. Leave empty to omit --name.",
121
value: defaultName,
122
});
123
}
extensions/vscode/src/test/extension.test.ts
+5
-15
@@ -1,7 +1,6 @@
1
import * as assert from "assert";
2
3
import { buildCommand, validateRelayUrl } from "../command";
4
-import { buildDefaultExposeName } from "../../../../utils/exposeName";
4
5
suite("Extension Test Suite", () => {
6
test("validateRelayUrl accepts only https URLs", () => {
@@ -10,12 +9,10 @@ suite("Extension Test Suite", () => {
9
assert.strictEqual(validateRelayUrl("not-a-url"), "Enter a valid https:// URL");
10
});
11
13
- test("buildCommand generates --name when empty and resolves unix portal binary after install", () => {
14
- const generatedName = buildDefaultExposeName("localhost:3000", "machine-seed");
12
+ test("buildCommand omits --name when empty and resolves unix portal binary after install", () => {
13
const command = buildCommand({
14
host: "localhost:3000",
15
name: "",
18
- nameSeed: "machine-seed",
16
relayList: "https://relay.example.com",
17
relayUrl: "https://relay.example.com",
18
thumbnail: "",
@@ -24,18 +21,14 @@ suite("Extension Test Suite", () => {
21
22
assert.match(command, /curl -fsSL https:\/\/relay\.example\.com\/install\.sh \| bash/);
23
assert.match(command, /PORTAL_BIN="\$\(command -v portal 2>\/dev\/null \|\| true\)"/);
27
- assert.match(
28
- command,
29
- new RegExp(`"\\$PORTAL_BIN" expose localhost:3000 --name ${generatedName} --relays https://relay\\.example\\.com`)
30
- );
24
+ assert.match(command, /"\$PORTAL_BIN" expose localhost:3000 --relays https:\/\/relay\.example\.com/);
25
+ assert.ok(!command.includes("--name"));
26
});
27
28
test("buildCommand can use the default public registry without --relays", () => {
34
- const generatedName = buildDefaultExposeName("localhost:3000", "machine-seed");
29
const command = buildCommand({
30
host: "localhost:3000",
31
name: "",
38
- nameSeed: "machine-seed",
32
relayList: "",
33
relayUrl: "",
34
thumbnail: "",
@@ -44,18 +37,15 @@ suite("Extension Test Suite", () => {
37
38
assert.ok(!command.includes("/install.sh"));
39
assert.ok(!command.includes("--relays"));
40
+ assert.ok(!command.includes("--name"));
41
assert.match(command, /portal CLI not found\. Install from a relay first or configure portal\.relayUrls\./);
48
- assert.match(
49
- command,
50
- new RegExp(`"\\$PORTAL_BIN" expose localhost:3000 --name ${generatedName}`)
51
- );
42
+ assert.match(command, /"\$PORTAL_BIN" expose localhost:3000/);
43
});
44
45
test("buildCommand uses explicit portal.exe path on windows", () => {
46
const command = buildCommand({
47
host: "localhost:3000",
48
name: "my-app",
58
- nameSeed: "machine-seed",
49
relayList: "https://relay.example.com",
50
relayUrl: "https://relay.example.com",
51
thumbnail: "https://example.com/thumb.png",
frontend/src/lib/exposeName.ts
renamed
frontend/src/lib/tunnelCommand.ts
+1
-1
@@ -3,7 +3,7 @@ import {
3
buildDefaultExposeName,
4
normalizeExposeName,
5
resolveExposeName,
6
-} from "../../../utils/exposeName";
6
+} from "@/lib/exposeName";
7
8
export type TunnelCommandOS = "unix" | "windows";
9
frontend/tsconfig.json
+1
-1
@@ -23,6 +23,6 @@
23
"noUnusedParameters": true,
24
"noFallthroughCasesInSwitch": true
25
},
26
- "include": ["src", "../utils/exposeName.ts"],
26
+ "include": ["src"],
27
"references": [{ "path": "./tsconfig.node.json" }]
28
}