import { env } from "cloudflare:workers";
import { GitStore } from "../git/store";
import { objectKey, STATIC_LIMITS } from "./config";
import type { ManifestFile } from "./config";
export type PlannedFile = { path: string; sha: string };
export type CollectedFiles = Record<string, ManifestFile>;
const TAR_BLOCK = 512;
const encoder = new TextEncoder();
const decoder = new TextDecoder();
export class DeployError extends Error {}
function normalizeFolder(folder: string): string {
return folder.replace(/^\/+|\/+$/g, "");
}
/** Normalizes an archive path relative to `folder`; null when outside it or unsafe. */
function relativePath(raw: string, folder: string): string | null {
const parts = raw
.replace(/^\.?\/+/, "")
.split("/")
.filter((part) => part && part !== ".");
if (parts.some((part) => part === "..")) return null;
const path = parts.join("/");
if (!folder) return path || null;
return path.startsWith(`${folder}/`) ? path.slice(folder.length + 1) : null;
}
/** Lists the files of a branch folder, bounded by the deploy file cap. */
export async function planGitFiles(
artifactsName: string,
sha: string,
folder: string,
maxFiles: number = STATIC_LIMITS.maxFiles,
): Promise<PlannedFile[]> {
const store = await GitStore.open(artifactsName);
try {
const commit = await store.commit(sha);