Bun.fileURLToPath: แปลง file URL เป็นพาธโดยไม่พังช่องว่างและอักขระ escape
new URL("data file.json", import.meta.url).pathname ดูเหมือนพาธ แต่ยังเป็นรูปแบบ URL ครับ ช่องว่างอาจอยู่เป็น %20 และกติกา Windows drive/UNC ต่างจากพาธ POSIX Bun.fileURLToPath แปลงตาม semantics ของระบบไฟล์ให้
WHY: URL กับ filesystem path เป็นคนละภาษา
เหมือนที่อยู่บนซองพัสดุกับทางเดินจริงในคลัง ทั้งสองชี้จุดเดียวกันแต่ใช้กฎ escape และตัวคั่นต่างกัน การหยิบ pathname ตรง ๆ คือเอาที่อยู่บนซองไปใช้เป็นทางเดิน อาจผ่านบนชื่อธรรมดาแล้วพังเมื่อเจอช่องว่างหรือ platform อื่น
HOW: ประกอบ URL ก่อน แล้วค่อยแปลงครั้งเดียว
const url = new URL("file:///tmp/showkhun%20notes/data.json");
const path = Bun.fileURLToPath(url);
if (path !== "/tmp/showkhun notes/data.json") {
throw new Error(`unexpected path: ${path}`);
}
const roundTrip = Bun.pathToFileURL(path);
if (!roundTrip.href.endsWith("showkhun%20notes/data.json")) {
throw new Error(`unexpected URL: ${roundTrip.href}`);
}
ในโมดูลจริงให้สร้าง new URL("./data.json", import.meta.url) ก่อน จึงค่อยแปลงเป็น path ตอน API ปลายทางต้องการ string path หาก API รับ URL ได้อยู่แล้ว ส่ง URL โดยตรงจะลดการแปลงไปกลับ
อย่ารับ file: URL จากผู้ใช้แล้วเปิดทันที การแปลงถูกต้องไม่ได้แปลว่าปลายทางอยู่ใน directory ที่อนุญาต ต้อง resolve, canonicalize เท่าที่ platform รองรับ และตรวจ boundary แยกต่างหาก โดยเฉพาะ service ที่ถือ secret
Recap
- อย่าใช้
.pathnameเป็นพาธโดยตรง - ใช้
Bun.fileURLToPathเพื่อ decode และจัดรูปแบบตาม platform - ใช้
Bun.pathToFileURLเมื่อต้องย้อนกลับ - ตรวจ allowed directory แยกจากการแปลงรูปแบบ