fix(media): normalize Windows file URLs
This commit is contained in:
parent
4583f88626
commit
b78aa7dc9e
@ -27,6 +27,27 @@ describe("splitMediaFromOutput", () => {
|
||||
expect(result.text).toBe("");
|
||||
});
|
||||
|
||||
it("normalizes Windows file URLs", () => {
|
||||
const result = splitMediaFromOutput("MEDIA:file:///C:/Users/pete/My%20File.png");
|
||||
const expected =
|
||||
process.platform === "win32" ? "C:\\Users\\pete\\My File.png" : "C:/Users/pete/My File.png";
|
||||
expect(result.mediaUrls).toEqual([expected]);
|
||||
expect(result.text).toBe("");
|
||||
});
|
||||
|
||||
it("accepts Windows drive letter paths", () => {
|
||||
const result = splitMediaFromOutput("MEDIA:C:/Users/pete/My File.png");
|
||||
expect(result.mediaUrls).toEqual(["C:/Users/pete/My File.png"]);
|
||||
expect(result.text).toBe("");
|
||||
});
|
||||
|
||||
it("accepts Windows drive letter paths with backslashes", () => {
|
||||
const filePath = "C:\\Users\\pete\\My File.png";
|
||||
const result = splitMediaFromOutput(`MEDIA:${filePath}`);
|
||||
expect(result.mediaUrls).toEqual([filePath]);
|
||||
expect(result.text).toBe("");
|
||||
});
|
||||
|
||||
it("keeps audio_as_voice detection stable across calls", () => {
|
||||
const input = "Hello [[audio_as_voice]]";
|
||||
const first = splitMediaFromOutput(input);
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
// Shared helpers for parsing MEDIA tokens from command/stdout text.
|
||||
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
import { parseFenceSpans } from "../markdown/fences.js";
|
||||
import { parseAudioTag } from "./audio-tags.js";
|
||||
|
||||
@ -7,7 +9,15 @@ import { parseAudioTag } from "./audio-tags.js";
|
||||
export const MEDIA_TOKEN_RE = /\bMEDIA:\s*`?([^\n]+)`?/gi;
|
||||
|
||||
export function normalizeMediaSource(src: string) {
|
||||
return src.startsWith("file://") ? src.replace("file://", "") : src;
|
||||
if (!src.startsWith("file://")) return src;
|
||||
try {
|
||||
const filePath = fileURLToPath(src);
|
||||
// Normalize drive-letter paths that appear as `/C:/...` on non-Windows platforms.
|
||||
return filePath.replace(/^\/([a-zA-Z]:[\\/])/, "$1");
|
||||
} catch {
|
||||
// Best-effort fallback for malformed file URLs.
|
||||
return src.replace("file://", "");
|
||||
}
|
||||
}
|
||||
|
||||
function cleanCandidate(raw: string) {
|
||||
@ -19,6 +29,8 @@ function isValidMedia(candidate: string, opts?: { allowSpaces?: boolean }) {
|
||||
if (candidate.length > 4096) return false;
|
||||
if (!opts?.allowSpaces && /\s/.test(candidate)) return false;
|
||||
if (/^https?:\/\//i.test(candidate)) return true;
|
||||
if (/^[a-zA-Z]:[\\/]/.test(candidate)) return true;
|
||||
if (candidate.startsWith("\\\\")) return true;
|
||||
if (candidate.startsWith("/")) return true;
|
||||
if (candidate.startsWith("./")) return true;
|
||||
if (candidate.startsWith("../")) return true;
|
||||
@ -118,6 +130,7 @@ export function splitMediaFromOutput(raw: string): {
|
||||
trimmedPayload.startsWith("./") ||
|
||||
trimmedPayload.startsWith("../") ||
|
||||
trimmedPayload.startsWith("~") ||
|
||||
/^[a-zA-Z]:[\\/]/.test(trimmedPayload) ||
|
||||
trimmedPayload.startsWith("file://");
|
||||
if (
|
||||
!unwrapped &&
|
||||
|
||||
Loading…
Reference in New Issue
Block a user