1import * as Effect from "effect/Effect";
2
3/** Validate an untrusted bundler output path before writing it to disk. */
4export const normalizeBundleFilePath = (input: string) =>
5 Effect.gen(function* () {
6 const normalized = input.replaceAll("\\", "/");
7 if (
8 normalized.length === 0 ||
9 normalized.startsWith("/") ||
10 /^[a-zA-Z]:\//.test(normalized)
11 ) {
12 return yield* Effect.fail(
13 new Error(`Invalid Compute bundle output path: ${input}`),
14 );
15 }
16 const segments = normalized.split("/");
17 if (
18 segments.some(
19 (segment) =>
20 segment.length === 0 || segment === "." || segment === "..",
21 )
22 ) {
23 return yield* Effect.fail(
24 new Error(`Invalid Compute bundle output path: ${input}`),
25 );
26 }
27 return segments.join("/");
28 });