globalThis.process ??= {};
globalThis.process.env ??= {};
import { r as __exportAll } from "./rolldown-runtime_-UtK6b3T.mjs";
import { d as mapContentError, l as jsonError, u as jsonOk } from "./crypto_CY2zBtG3.mjs";
import { f as requireRole } from "./engine-custom_BJVTPCgT.mjs";
import { c as deleteMenu, d as moveMenuItem, f as removeMenuItem, h as updateMenuItem, i as menusActorFromPrincipal, l as getMenuTree, m as updateMenu, n as getMenusDb, o as addMenuItem, p as reorderMenuItems, r as mapMenuError, s as createMenu, u as listMenus } from "./menus_Gno2rDek.mjs";
import { i as buildServiceTokenResolver, r as buildAuthEngine, t as ROLE_HIERARCHY } from "./admin-engine_Cqzo5vQB.mjs";
import { c as assertCsrf, s as resolveSession } from "./auth_B0DWM0G6.mjs";
import { env } from "cloudflare:workers";
//#region src/pages/api/admin/menus.ts
var menus_exports = /* @__PURE__ */ __exportAll({
	DELETE: () => DELETE,
	GET: () => GET,
	PATCH: () => PATCH,
	POST: () => POST,
	prerender: () => false
});
function parseTarget(raw) {
	if (typeof raw !== "object" || raw === null) throw new Error("validation");
	const row = raw;
	if (row.kind === "url") {
		if (typeof row.url !== "string" || !row.url.trim()) throw new Error("validation");
		return {
			kind: "url",
			url: row.url.trim(),
			...row.openInNew === true ? { openInNew: true } : {}
		};
	}
	if (row.kind === "entity") {
		if (typeof row.entityType !== "string" || !row.entityType.trim()) throw new Error("validation");
		if (typeof row.entityId !== "string" || !row.entityId.trim()) throw new Error("validation");
		return {
			kind: "entity",
			entityType: row.entityType.trim(),
			entityId: row.entityId.trim(),
			...row.openInNew === true ? { openInNew: true } : {}
		};
	}
	throw new Error("validation");
}
function parsePostBody(data) {
	if (typeof data !== "object" || data === null) throw new Error("validation");
	const raw = data;
	if (raw.action === "createMenu") {
		const row = data;
		if (typeof row.key !== "string" || !row.key.trim()) throw new Error("validation");
		if (typeof row.label !== "string" || !row.label.trim()) throw new Error("validation");
		return {
			action: "createMenu",
			key: row.key.trim(),
			label: row.label.trim()
		};
	}
	if (raw.action === "addItem") {
		const row = data;
		if (typeof row.menuId !== "string" || !row.menuId.trim()) throw new Error("validation");
		if (typeof row.label !== "string" || !row.label.trim()) throw new Error("validation");
		const parentId = row.parentId === void 0 || row.parentId === null ? void 0 : typeof row.parentId === "string" && row.parentId.trim() ? row.parentId.trim() : (() => {
			throw new Error("validation");
		})();
		return {
			action: "addItem",
			menuId: row.menuId.trim(),
			label: row.label.trim(),
			target: parseTarget(row.target),
			...parentId ? { parentId } : {}
		};
	}
	if (raw.action === "moveItem") {
		const row = data;
		if (typeof row.itemId !== "string" || !row.itemId.trim()) throw new Error("validation");
		const newParentId = row.newParentId === null ? null : typeof row.newParentId === "string" && row.newParentId.trim() ? row.newParentId.trim() : (() => {
			throw new Error("validation");
		})();
		if (typeof row.newPosition !== "number" || !Number.isInteger(row.newPosition) || row.newPosition < 0) throw new Error("validation");
		return {
			action: "moveItem",
			itemId: row.itemId.trim(),
			newParentId,
			newPosition: row.newPosition
		};
	}
	if (raw.action === "reorderItems") {
		const row = data;
		if (typeof row.menuId !== "string" || !row.menuId.trim()) throw new Error("validation");
		const parentId = row.parentId === null ? null : typeof row.parentId === "string" && row.parentId.trim() ? row.parentId.trim() : (() => {
			throw new Error("validation");
		})();
		if (!Array.isArray(row.orderedIds) || row.orderedIds.some((id) => typeof id !== "string" || !id.trim())) throw new Error("validation");
		return {
			action: "reorderItems",
			menuId: row.menuId.trim(),
			parentId,
			orderedIds: row.orderedIds.map((id) => id.trim())
		};
	}
	throw new Error("validation");
}
function parsePatchBody(data) {
	if (typeof data !== "object" || data === null) throw new Error("validation");
	const raw = data;
	if (raw.resource === "menu") {
		const row = data;
		if (typeof row.menuId !== "string" || !row.menuId.trim()) throw new Error("validation");
		if (typeof row.patch !== "object" || row.patch === null) throw new Error("validation");
		const patch = row.patch;
		if (patch.label !== void 0 && (typeof patch.label !== "string" || !patch.label.trim())) throw new Error("validation");
		return {
			resource: "menu",
			menuId: row.menuId.trim(),
			patch: { ...patch.label !== void 0 ? { label: patch.label.trim() } : {} }
		};
	}
	if (raw.resource === "item") {
		const row = data;
		if (typeof row.itemId !== "string" || !row.itemId.trim()) throw new Error("validation");
		if (typeof row.patch !== "object" || row.patch === null) throw new Error("validation");
		const patch = row.patch;
		if (patch.label !== void 0 && (typeof patch.label !== "string" || !patch.label.trim())) throw new Error("validation");
		if (patch.openInNew !== void 0 && typeof patch.openInNew !== "boolean") throw new Error("validation");
		return {
			resource: "item",
			itemId: row.itemId.trim(),
			patch: {
				...patch.label !== void 0 ? { label: patch.label.trim() } : {},
				...patch.target !== void 0 ? { target: parseTarget(patch.target) } : {},
				...patch.openInNew !== void 0 ? { openInNew: patch.openInNew } : {}
			}
		};
	}
	throw new Error("validation");
}
function parseDeleteBody(data) {
	if (typeof data !== "object" || data === null) throw new Error("validation");
	const raw = data;
	if (raw.resource === "menu") {
		const row = data;
		if (typeof row.menuId !== "string" || !row.menuId.trim()) throw new Error("validation");
		return {
			resource: "menu",
			menuId: row.menuId.trim()
		};
	}
	if (raw.resource === "item") {
		const row = data;
		if (typeof row.itemId !== "string" || !row.itemId.trim()) throw new Error("validation");
		return {
			resource: "item",
			itemId: row.itemId.trim()
		};
	}
	throw new Error("validation");
}
async function readJson(request) {
	try {
		return await request.json();
	} catch {
		throw new Error("invalid_json");
	}
}
var GET = async ({ request, cookies, url }) => {
	try {
		const { principal } = await resolveSession(request, buildAuthEngine(env), cookies, buildServiceTokenResolver(env));
		requireRole("admin", ROLE_HIERARCHY)(principal);
		const db = getMenusDb(env);
		const key = url.searchParams.get("key")?.trim();
		if (key) {
			const tree = await getMenuTree(db, key);
			return jsonOk({ tree });
		}
		const menus = await listMenus(db);
		return jsonOk({ menus });
	} catch (error) {
		const mapped = mapMenuError(error);
		if (mapped.status !== 500) return mapped;
		return mapContentError(error);
	}
};
var POST = async ({ request, cookies }) => {
	try {
		const { principal, authMode } = await resolveSession(request, buildAuthEngine(env), cookies, buildServiceTokenResolver(env));
		requireRole("admin", ROLE_HIERARCHY)(principal);
		assertCsrf(request, {
			authMode,
			siteOrigin: env.SITE_ORIGIN
		});
		const actor = menusActorFromPrincipal(principal);
		const db = getMenusDb(env);
		const parsed = parsePostBody(await readJson(request));
		if (parsed.action === "createMenu") {
			const menu = await createMenu(db, actor, {
				key: parsed.key,
				label: parsed.label
			});
			return jsonOk({ menu }, 201);
		}
		if (parsed.action === "addItem") {
			const item = await addMenuItem(db, actor, parsed.menuId, {
				label: parsed.label,
				target: parsed.target,
				...parsed.parentId ? { parentId: parsed.parentId } : {}
			});
			return jsonOk({ item }, 201);
		}
		if (parsed.action === "moveItem") {
			const item = await moveMenuItem(db, actor, parsed.itemId, {
				newParentId: parsed.newParentId,
				newPosition: parsed.newPosition
			});
			return jsonOk({ item });
		}
		const reorder = parsed;
		await reorderMenuItems(db, actor, reorder.menuId, reorder.parentId, reorder.orderedIds);
		return jsonOk({ ok: true });
	} catch (error) {
		if (error.message === "validation") return jsonError(400, "validation_error", "Invalid menus request.");
		if (error.message === "invalid_json") return jsonError(400, "validation_error", "Invalid request body.");
		const mapped = mapMenuError(error);
		if (mapped.status !== 500) return mapped;
		return mapContentError(error);
	}
};
var PATCH = async ({ request, cookies }) => {
	try {
		const { principal, authMode } = await resolveSession(request, buildAuthEngine(env), cookies, buildServiceTokenResolver(env));
		requireRole("admin", ROLE_HIERARCHY)(principal);
		assertCsrf(request, {
			authMode,
			siteOrigin: env.SITE_ORIGIN
		});
		const actor = menusActorFromPrincipal(principal);
		const db = getMenusDb(env);
		const parsed = parsePatchBody(await readJson(request));
		if (parsed.resource === "menu") {
			const menu = await updateMenu(db, actor, parsed.menuId, parsed.patch);
			return jsonOk({ menu });
		}
		const item = await updateMenuItem(db, actor, parsed.itemId, parsed.patch);
		return jsonOk({ item });
	} catch (error) {
		if (error.message === "validation") return jsonError(400, "validation_error", "Invalid menus request.");
		if (error.message === "invalid_json") return jsonError(400, "validation_error", "Invalid request body.");
		const mapped = mapMenuError(error);
		if (mapped.status !== 500) return mapped;
		return mapContentError(error);
	}
};
var DELETE = async ({ request, cookies }) => {
	try {
		const { principal, authMode } = await resolveSession(request, buildAuthEngine(env), cookies, buildServiceTokenResolver(env));
		requireRole("admin", ROLE_HIERARCHY)(principal);
		assertCsrf(request, {
			authMode,
			siteOrigin: env.SITE_ORIGIN
		});
		const actor = menusActorFromPrincipal(principal);
		const db = getMenusDb(env);
		const parsed = parseDeleteBody(await readJson(request));
		if (parsed.resource === "menu") {
			await deleteMenu(db, actor, parsed.menuId);
			return jsonOk({
				ok: true,
				menuId: parsed.menuId
			});
		}
		await removeMenuItem(db, actor, parsed.itemId);
		return jsonOk({
			ok: true,
			itemId: parsed.itemId
		});
	} catch (error) {
		if (error.message === "validation") return jsonError(400, "validation_error", "Invalid menus request.");
		if (error.message === "invalid_json") return jsonError(400, "validation_error", "Invalid request body.");
		const mapped = mapMenuError(error);
		if (mapped.status !== 500) return mapped;
		return mapContentError(error);
	}
};
//#endregion
//#region \0virtual:astro:page:src/pages/api/admin/menus@_@ts
var page = () => menus_exports;
//#endregion
export { page };
