import { isAbsolute, join, relative, resolve, sep } from "node:path"; import { WorkspaceFileBoundaryError, readWorkspaceFileNoFollow, } from "../security/workspaceFiles.js"; export interface DeliverableFile { readonly path: string; readonly name: string; readonly data: Buffer; } const DELIVERABLE_CPH_DIRECTORY = "inbox"; export async function resolveDeliverableFile( requestedPath: string, workspaceRoot: string, workspaceDir: string, maxBytes?: number, ): Promise { const token = requestedPath.trim(); if (token === "") return null; for (const candidate of candidatePaths(token)) { assertNotPlatformRuntimePath(candidate, workspaceDir); try { return await readWorkspaceFileNoFollow(workspaceRoot, workspaceDir, candidate, maxBytes); } catch (error) { if (!(error instanceof WorkspaceFileBoundaryError) || error.reason !== "not_found") { throw error; } // Try the explicit workspace/build fallback for a bare filename. No // candidate outside the project workspace is ever considered. } } return null; } function assertNotPlatformRuntimePath(candidate: string, workspaceDir: string): void { const workspace = resolve(workspaceDir); const target = isAbsolute(candidate) ? resolve(candidate) : resolve(workspace, candidate); const rel = relative(workspace, target); const components = rel.split(sep); if (components[0] === ".cph" && components[1] !== DELIVERABLE_CPH_DIRECTORY) { throw new WorkspaceFileBoundaryError( `platform runtime files cannot be delivered: ${candidate}`, candidate, "boundary", ); } } function candidatePaths(token: string): string[] { if (isAbsolute(token)) return [token]; const candidates = [token]; if (!token.includes("/") && !token.includes("\\")) { candidates.push(join("build", token)); } return [...new Set(candidates)]; }