globalThis.process ??= {};
globalThis.process.env ??= {};
import { E as eq, T as and } from "./d1_DTqC4o_t.mjs";
import { l as jsonError } from "./crypto_CY2zBtG3.mjs";
import { g as comments, n as getFullDb, v as isCommentError } from "./db_DZJ1iBSP.mjs";
//#region src/lib/comments.ts
/** Comments db handle — reuses the host full-db client typed to CommentsSchema. */
function getCommentsDb(env) {
	return getFullDb(env).db;
}
/** Derive moderation capability from role — U7-ready (never hardcode canModerate:true). */
function moderatorActorFromPrincipal(principal) {
	const roles = principal.roles ?? [];
	return {
		id: principal.userId,
		canModerate: roles.includes("admin")
	};
}
function guestAuthorFromForm(fields) {
	return {
		kind: "guest",
		name: fields.name,
		...fields.email ? { email: fields.email } : {},
		...fields.url ? { url: fields.url } : {}
	};
}
function userAuthorFromPrincipal(principal) {
	return {
		kind: "user",
		userId: principal.userId
	};
}
/** F1 — allow only http(s) author URLs; reject scheme-relative and exotic schemes. */
function safeAuthorUrl(url) {
	if (!url || typeof url !== "string") return null;
	const trimmed = url.trim();
	if (!trimmed || trimmed.startsWith("//")) return null;
	try {
		const parsed = new URL(trimmed);
		if (parsed.protocol === "http:" || parsed.protocol === "https:") return trimmed;
	} catch {
		return null;
	}
	return null;
}
/**
* U1 orphan-purge binding (U5 spec §6): content rows are HARD-deleted by `content.remove`
* (DELETE ... FROM content_entries). `comments.target_id` is polymorphic with NO FK to
* content_entries, so a permanent content delete would orphan its comment rows. The host
* cascades by target here. Call ONLY on hard-delete/purge — never on soft-trash (reversible).
*/
async function deleteCommentsByTarget(db, target) {
	await db.delete(comments).where(and(eq(comments.targetType, target.type), eq(comments.targetId, target.id)));
}
function commentErrorMessage(error) {
	if (error instanceof Error) return error.message;
	return "Comment request failed.";
}
function mapCommentError(error) {
	if (isCommentError(error)) {
		const code = error.code;
		if (code === "COMMENT_VALIDATION") return jsonError(422, "validation_error", commentErrorMessage(error));
		if (code === "COMMENT_SANITIZATION") return jsonError(500, "internal_error", "Comment could not be sanitized.");
		if (code === "COMMENT_AUTHZ") return jsonError(403, "forbidden", commentErrorMessage(error));
		if (code === "COMMENT_NOT_FOUND") return jsonError(404, "not_found", commentErrorMessage(error));
		if (code === "COMMENT_INVALID_CURSOR") return jsonError(400, "validation_error", "That page cursor is invalid.");
	}
	return jsonError(500, "internal_error", "internal error");
}
//#endregion
export { moderatorActorFromPrincipal as a, mapCommentError as i, getCommentsDb as n, safeAuthorUrl as o, guestAuthorFromForm as r, userAuthorFromPrincipal as s, deleteCommentsByTarget as t };
