import { badRequest, forbidden } from "../errors";
import type { GitStore } from "../git/store";
import { MAX_POINTER_BYTES, parseLfsPointer } from "../lfs/pointer";
const MAX_ATTRIBUTES_BYTES = 64 * 1024;
const MAX_ATTRIBUTE_RULES = 500;
const decoder = new TextDecoder();
type Rule = { regex: RegExp; anchored: boolean; lfs: boolean };
const REGEX_SPECIAL = /[.+^${}()|\\]/;
/** gitattributes/fnmatch globs: `*` and `?` stay within a segment, `**` spans them, `[...]` is a class. */
function attributeGlob(pattern: string): RegExp {
let source = "";
for (let index = 0; index < pattern.length; index++) {
const char = pattern[index];
if (char === "*" && pattern[index + 1] === "*") {
const slash = pattern[index + 2] === "/";
source += slash ? "(?:.*/)?" : ".*";
index += slash ? 2 : 1;
} else if (char === "*") source += "[^/]*";
else if (char === "?") source += "[^/]";
else if (char === "[") {
const close = pattern.indexOf("]", index + 2);
if (close === -1) {
source += "\\[";
continue;
}
const body = pattern
.slice(index + 1, close)
.replace(/^!/, "^")
.replace(/\\/g, "\\\\");
source += `[${body}]`;
index = close;
} else if (char === "\\" && index + 1 < pattern.length) {
index++;
source += pattern[index].replace(/[.*+?^${}()|[\]\\/]/g, "\\$&");
} else source += REGEX_SPECIAL.test(char) || char === "]" ? `\\${char}` : char;
}