refactor: rename services to scripts and extract reusable components

This commit is contained in:
Mohamed Boudra
2026-04-09 18:54:25 +07:00
parent 5cf806dc77
commit 397d454de0
48 changed files with 1356 additions and 983 deletions
@@ -0,0 +1,29 @@
import { describe, expect, it } from "vitest";
import { buildScriptHostname } from "./script-hostname.js";
describe("buildScriptHostname", () => {
it("slugifies script names with spaces on default branches", () => {
expect(buildScriptHostname(null, "npm run dev")).toBe("npm-run-dev.localhost");
});
it("slugifies script names with special characters", () => {
expect(buildScriptHostname(null, "Web/API @ Dev")).toBe("web-api-dev.localhost");
});
it("omits the branch prefix for main and master", () => {
expect(buildScriptHostname("main", "npm run dev")).toBe("npm-run-dev.localhost");
expect(buildScriptHostname("master", "npm run dev")).toBe("npm-run-dev.localhost");
});
it("adds a slugified branch prefix for non-default branches", () => {
expect(buildScriptHostname("feature/cool stuff", "api")).toBe(
"feature-cool-stuff.api.localhost",
);
});
it("slugifies both the branch name and script name together", () => {
expect(buildScriptHostname("feat/add auth", "npm run dev")).toBe(
"feat-add-auth.npm-run-dev.localhost",
);
});
});
@@ -1,7 +1,7 @@
import { slugify } from "./worktree.js";
export function buildServiceHostname(branchName: string | null, serviceName: string): string {
const serviceHostnameLabel = slugify(serviceName);
export function buildScriptHostname(branchName: string | null, scriptName: string): string {
const serviceHostnameLabel = slugify(scriptName);
const isDefaultBranch =
branchName === null || branchName === "main" || branchName === "master";
@@ -1,29 +0,0 @@
import { describe, expect, it } from "vitest";
import { buildServiceHostname } from "./service-hostname.js";
describe("buildServiceHostname", () => {
it("slugifies service names with spaces on default branches", () => {
expect(buildServiceHostname(null, "npm run dev")).toBe("npm-run-dev.localhost");
});
it("slugifies service names with special characters", () => {
expect(buildServiceHostname(null, "Web/API @ Dev")).toBe("web-api-dev.localhost");
});
it("omits the branch prefix for main and master", () => {
expect(buildServiceHostname("main", "npm run dev")).toBe("npm-run-dev.localhost");
expect(buildServiceHostname("master", "npm run dev")).toBe("npm-run-dev.localhost");
});
it("adds a slugified branch prefix for non-default branches", () => {
expect(buildServiceHostname("feature/cool stuff", "api")).toBe(
"feature-cool-stuff.api.localhost",
);
});
it("slugifies both the branch name and service name together", () => {
expect(buildServiceHostname("feat/add auth", "npm run dev")).toBe(
"feat-add-auth.npm-run-dev.localhost",
);
});
});
+10 -10
View File
@@ -24,7 +24,7 @@ interface PaseoConfig {
teardown?: string[];
terminals?: WorktreeTerminalConfig[];
};
services?: Record<string, ServiceConfig>;
scripts?: Record<string, ScriptConfig>;
}
const execAsync = promisify(exec);
@@ -90,7 +90,7 @@ export interface WorktreeTerminalConfig {
command: string;
}
export interface ServiceConfig {
export interface ScriptConfig {
command: string;
port?: number; // explicit port override, otherwise auto-assigned
}
@@ -205,15 +205,15 @@ export function getWorktreeTerminalSpecs(repoRoot: string): WorktreeTerminalConf
return specs;
}
export function getServiceConfigs(repoRoot: string): Map<string, ServiceConfig> {
export function getScriptConfigs(repoRoot: string): Map<string, ScriptConfig> {
const config = readPaseoConfig(repoRoot);
const services = config?.services;
if (!services || typeof services !== "object") {
const scripts = config?.scripts;
if (!scripts || typeof scripts !== "object") {
return new Map();
}
const result = new Map<string, ServiceConfig>();
for (const [name, entry] of Object.entries(services)) {
const result = new Map<string, ScriptConfig>();
for (const [name, entry] of Object.entries(scripts)) {
if (!entry || typeof entry !== "object") {
continue;
}
@@ -227,13 +227,13 @@ export function getServiceConfigs(repoRoot: string): Map<string, ServiceConfig>
continue;
}
const serviceConfig: ServiceConfig = { command };
const scriptConfig: ScriptConfig = { command };
if (typeof entry.port === "number" && Number.isFinite(entry.port)) {
serviceConfig.port = entry.port;
scriptConfig.port = entry.port;
}
result.set(name, serviceConfig);
result.set(name, scriptConfig);
}
return result;