From a0d98a573b80bcdcdae979e2a0870d8cf62cd5ce Mon Sep 17 00:00:00 2001 From: elpresidank Date: Thu, 4 Jun 2026 05:56:53 -0500 Subject: [PATCH] Use Match for CLI MIME detection --- ts/EFFECT_NATIVE_REWRITE_AUDIT.md | 15 ++++++++ ts/packages/cli/package.json | 2 +- ts/packages/cli/src/__tests__/library.test.ts | 22 ++++++++++++ ts/packages/cli/src/commands/library.ts | 34 +++++++------------ 4 files changed, 51 insertions(+), 22 deletions(-) create mode 100644 ts/packages/cli/src/__tests__/library.test.ts diff --git a/ts/EFFECT_NATIVE_REWRITE_AUDIT.md b/ts/EFFECT_NATIVE_REWRITE_AUDIT.md index 3fb9cde4..63ee2dc8 100644 --- a/ts/EFFECT_NATIVE_REWRITE_AUDIT.md +++ b/ts/EFFECT_NATIVE_REWRITE_AUDIT.md @@ -499,6 +499,21 @@ Notes: - `bun run --cwd ts/packages/flow test -- src/__tests__/agent-service.test.ts` - `cd ts && bun run check:tsgo` +### 2026-06-04: CLI Library MIME Match Slice + +- Status: migrated and package-verified. +- Completed: + - `ts/packages/cli/src/commands/library.ts` now uses `effect/Match` for + extension-to-MIME mapping instead of a native `switch`. + - `guessMimeType` is exported for focused CLI helper coverage. + - CLI tests now cover known extensions, case normalization, `html`/`htm` + aliases, and fallback behavior for unknown or extensionless paths. + - `ts/packages/cli/package.json` excludes `dist/**` from Vitest so built + test output is not executed a second time after root build lanes. +- Verification: + - `bun run --cwd ts/packages/cli test -- src/__tests__/library.test.ts` + - `cd ts && bun run check:tsgo` + ### 2026-06-02: RAG And Agent Requestor Bridge Slice - Status: migrated, root-verified, committed, and pushed. diff --git a/ts/packages/cli/package.json b/ts/packages/cli/package.json index 0788b439..e422cbd1 100644 --- a/ts/packages/cli/package.json +++ b/ts/packages/cli/package.json @@ -9,7 +9,7 @@ "build": "bunx --bun tsc", "dev": "tsc --watch", "clean": "rm -rf dist", - "test": "bunx --bun vitest run --passWithNoTests" + "test": "bunx --bun vitest run --passWithNoTests --exclude=dist/**" }, "dependencies": { "@trustgraph/base": "workspace:*", diff --git a/ts/packages/cli/src/__tests__/library.test.ts b/ts/packages/cli/src/__tests__/library.test.ts new file mode 100644 index 00000000..b65f4565 --- /dev/null +++ b/ts/packages/cli/src/__tests__/library.test.ts @@ -0,0 +1,22 @@ +import { describe, expect, it } from "vitest"; +import { guessMimeType } from "../commands/library.js"; + +describe("library CLI helpers", () => { + it("detects known MIME types through the Match-backed extension mapper", () => { + expect(guessMimeType("paper.pdf")).toBe("application/pdf"); + expect(guessMimeType("notes.TXT")).toBe("text/plain"); + expect(guessMimeType("readme.md")).toBe("text/markdown"); + expect(guessMimeType("index.html")).toBe("text/html"); + expect(guessMimeType("partial.htm")).toBe("text/html"); + expect(guessMimeType("data.json")).toBe("application/json"); + expect(guessMimeType("table.csv")).toBe("text/csv"); + expect(guessMimeType("brief.docx")).toBe( + "application/vnd.openxmlformats-officedocument.wordprocessingml.document", + ); + }); + + it("falls back for unknown or extensionless paths", () => { + expect(guessMimeType("archive.bin")).toBe("application/octet-stream"); + expect(guessMimeType("README")).toBe("application/octet-stream"); + }); +}); diff --git a/ts/packages/cli/src/commands/library.ts b/ts/packages/cli/src/commands/library.ts index 11ef23f1..0369fb90 100644 --- a/ts/packages/cli/src/commands/library.ts +++ b/ts/packages/cli/src/commands/library.ts @@ -5,7 +5,7 @@ */ import type { Command } from "commander"; -import { Effect } from "effect"; +import { Effect, Match } from "effect"; import { cliCommandError, withSocket, writeJson } from "./util.js"; function basenamePath(filepath: string): string { @@ -15,27 +15,19 @@ function basenamePath(filepath: string): string { } /** Simple MIME-type lookup by file extension. */ -function guessMimeType(filepath: string): string { +export function guessMimeType(filepath: string): string { const ext = filepath.split(".").pop()?.toLowerCase(); - switch (ext) { - case "pdf": - return "application/pdf"; - case "txt": - return "text/plain"; - case "md": - return "text/markdown"; - case "html": - case "htm": - return "text/html"; - case "json": - return "application/json"; - case "csv": - return "text/csv"; - case "docx": - return "application/vnd.openxmlformats-officedocument.wordprocessingml.document"; - default: - return "application/octet-stream"; - } + return Match.value(ext).pipe( + Match.when("pdf", () => "application/pdf"), + Match.when("txt", () => "text/plain"), + Match.when("md", () => "text/markdown"), + Match.when("html", () => "text/html"), + Match.when("htm", () => "text/html"), + Match.when("json", () => "application/json"), + Match.when("csv", () => "text/csv"), + Match.when("docx", () => "application/vnd.openxmlformats-officedocument.wordprocessingml.document"), + Match.orElse(() => "application/octet-stream"), + ); } export function registerLibraryCommands(program: Command): void {