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 }