globalThis.process ??= {};
globalThis.process.env ??= {};
import { r as __exportAll } from "./rolldown-runtime_-UtK6b3T.mjs";
import { A as getById, K as assertCanModify, c as isEntityId, d as mapContentError, k as ContentNotFoundError, l as jsonError, u as jsonOk } from "./crypto_CY2zBtG3.mjs";
import { n as getFullDb } from "./db_DZJ1iBSP.mjs";
import { K as updateGroup, R as resolveGroups, S as getEntityValues, W as setEntityValues, _ as deleteGroup, d as createGroup, g as deleteEntityValues, o as assertCanEditFields, s as assertCanManageGroups, w as listGroups } from "./dist_C9SfSFSK.mjs";
import { f as requireRole } from "./engine-custom_BJVTPCgT.mjs";
import { i as buildServiceTokenResolver, r as buildAuthEngine, t as ROLE_HIERARCHY } from "./admin-engine_Cqzo5vQB.mjs";
import { c as assertCsrf, s as resolveSession, t as actorFromPrincipal } from "./auth_B0DWM0G6.mjs";
import { a as mapFieldError, i as getFieldsDb, n as contentActorForFields, r as fieldsActorFromPrincipal, t as DEFAULT_CONTENT_FIELD_GROUP } from "./fields_C_f3cBnT.mjs";
import { env } from "cloudflare:workers";
//#region src/pages/api/admin/fields.ts
var fields_exports = /* @__PURE__ */ __exportAll({
	DELETE: () => DELETE,
	GET: () => GET,
	POST: () => POST,
	prerender: () => false
});
function groupIdOf(group) {
	return group.id ?? group.key;
}
function parseSetValuesBody(data) {
	if (typeof data !== "object" || data === null) throw new Error("validation");
	const raw = data;
	if (raw.action !== "setValues") throw new Error("validation");
	if (!isEntityId(raw.entityId)) throw new Error("validation");
	if (!Array.isArray(raw.groups) || raw.groups.length === 0) throw new Error("validation");
	const groups = raw.groups.map((item) => {
		if (typeof item !== "object" || item === null) throw new Error("validation");
		const row = item;
		if (typeof row.groupId !== "string" || !row.groupId.trim()) throw new Error("validation");
		if (typeof row.values !== "object" || row.values === null || Array.isArray(row.values)) throw new Error("validation");
		return {
			groupId: row.groupId.trim(),
			values: row.values
		};
	});
	return {
		action: "setValues",
		entityId: raw.entityId,
		groups
	};
}
function parseGroupMutationBody(data) {
	if (typeof data !== "object" || data === null) throw new Error("validation");
	const raw = data;
	if (raw.action === "createGroup") {
		const group = data.group;
		if (typeof group !== "object" || group === null) throw new Error("validation");
		return {
			action: "createGroup",
			group
		};
	}
	if (raw.action === "updateGroup") {
		const id = data.id;
		const patch = data.patch;
		if (typeof id !== "string" || !id.trim()) throw new Error("validation");
		if (typeof patch !== "object" || patch === null) throw new Error("validation");
		return {
			action: "updateGroup",
			id: id.trim(),
			patch
		};
	}
	if (raw.action === "deleteGroup") {
		const id = data.id;
		if (typeof id !== "string" || !id.trim()) throw new Error("validation");
		return {
			action: "deleteGroup",
			id: id.trim()
		};
	}
	throw new Error("validation");
}
async function loadContentEntry(env, entryId, principal) {
	const contentDb = getFullDb(env).db;
	const entry = await getById(contentDb, entryId, actorFromPrincipal(principal));
	if (!entry) throw new ContentNotFoundError(entryId);
	return entry;
}
var GET = async ({ request, cookies, url }) => {
	try {
		const { principal } = await resolveSession(request, buildAuthEngine(env), cookies, buildServiceTokenResolver(env));
		const db = getFieldsDb(env);
		const resource = url.searchParams.get("resource");
		if (resource === "groups") {
			requireRole("admin", ROLE_HIERARCHY)(principal);
			const entityType = url.searchParams.get("entityType") ?? void 0;
			const subType = url.searchParams.get("subType") ?? void 0;
			const groups = await listGroups(db, {
				...entityType ? { entityType } : {},
				...subType ? { subType } : {}
			});
			return jsonOk({ groups });
		}
		if (resource === "resolve-groups") {
			requireRole("editor", ROLE_HIERARCHY)(principal);
			const entityType = url.searchParams.get("entityType");
			if (!entityType) return jsonError(400, "validation_error", "entityType is required.");
			const subType = url.searchParams.get("subType") ?? void 0;
			const groups = await resolveGroups(db, {
				entityType,
				subType,
				codeGroups: [DEFAULT_CONTENT_FIELD_GROUP]
			});
			return jsonOk({ groups });
		}
		requireRole("editor", ROLE_HIERARCHY)(principal);
		const entityId = url.searchParams.get("entityId");
		if (!isEntityId(entityId)) return jsonError(400, "validation_error", "entityId must be a valid UUID.");
		const contentActor = contentActorForFields(principal);
		const entry = await loadContentEntry(env, entityId, principal);
		assertCanModify(contentActor, "update", entry.author, entry.id);
		const subType = url.searchParams.get("subType") ?? void 0;
		const values = await getEntityValues(db, {
			entityType: "content",
			entityId: entry.id
		}, {
			entityType: "content",
			subType,
			codeGroups: [DEFAULT_CONTENT_FIELD_GROUP]
		});
		return jsonOk({ values });
	} catch (error) {
		const mapped = mapFieldError(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));
		assertCsrf(request, {
			authMode,
			siteOrigin: env.SITE_ORIGIN
		});
		let body;
		try {
			body = await request.json();
		} catch {
			return jsonError(400, "validation_error", "Invalid request body.");
		}
		const action = body.action;
		const db = getFieldsDb(env);
		const fieldsActor = fieldsActorFromPrincipal(principal);
		if (action === "setValues") {
			requireRole("editor", ROLE_HIERARCHY)(principal);
			const parsed = parseSetValuesBody(body);
			const contentActor = contentActorForFields(principal);
			const entry = await loadContentEntry(env, parsed.entityId, principal);
			assertCanModify(contentActor, "update", entry.author, entry.id);
			assertCanEditFields(fieldsActor);
			const resolved = await resolveGroups(db, {
				entityType: "content",
				subType: entry.type,
				codeGroups: [DEFAULT_CONTENT_FIELD_GROUP]
			});
			for (const { groupId, values } of parsed.groups) {
				const matched = resolved.find((g) => groupIdOf(g) === groupId);
				if (!matched) return jsonError(400, "validation_error", `Unknown field group: ${groupId}`);
				await setEntityValues(db, fieldsActor, {
					ref: {
						entityType: "content",
						entityId: entry.id
					},
					groupId,
					values,
					resolved: matched
				});
			}
			return jsonOk({
				ok: true,
				entityId: entry.id
			});
		}
		requireRole("admin", ROLE_HIERARCHY)(principal);
		assertCanManageGroups(fieldsActor);
		const mutation = parseGroupMutationBody(body);
		if (mutation.action === "createGroup") {
			const created = await createGroup(db, fieldsActor, mutation.group, [DEFAULT_CONTENT_FIELD_GROUP]);
			return jsonOk({ group: created });
		}
		if (mutation.action === "updateGroup") {
			const updated = await updateGroup(db, fieldsActor, mutation.id, mutation.patch, [DEFAULT_CONTENT_FIELD_GROUP]);
			return jsonOk({ group: updated });
		}
		await deleteGroup(db, fieldsActor, mutation.id);
		return jsonOk({
			ok: true,
			id: mutation.id
		});
	} catch (error) {
		if (error.message === "validation") return jsonError(400, "validation_error", "Invalid fields request.");
		const mapped = mapFieldError(error);
		if (mapped.status !== 500) return mapped;
		return mapContentError(error);
	}
};
var DELETE = async ({ request, cookies, url }) => {
	try {
		const { principal, authMode } = await resolveSession(request, buildAuthEngine(env), cookies, buildServiceTokenResolver(env));
		requireRole("editor", ROLE_HIERARCHY)(principal);
		assertCsrf(request, {
			authMode,
			siteOrigin: env.SITE_ORIGIN
		});
		const entityId = url.searchParams.get("entityId");
		if (!isEntityId(entityId)) return jsonError(400, "validation_error", "entityId must be a valid UUID.");
		const contentActor = contentActorForFields(principal);
		const fieldsActor = fieldsActorFromPrincipal(principal);
		const db = getFieldsDb(env);
		const entry = await loadContentEntry(env, entityId, principal);
		assertCanModify(contentActor, "update", entry.author, entry.id);
		assertCanEditFields(fieldsActor);
		await deleteEntityValues(db, {
			entityType: "content",
			entityId: entry.id
		});
		return jsonOk({
			ok: true,
			entityId: entry.id
		});
	} catch (error) {
		const mapped = mapFieldError(error);
		if (mapped.status !== 500) return mapped;
		return mapContentError(error);
	}
};
//#endregion
//#region \0virtual:astro:page:src/pages/api/admin/fields@_@ts
var page = () => fields_exports;
//#endregion
export { page };
