import { t as JSONRPCMessageSchema } from "./src-CracgD9q.mjs";
import { randomUUID } from "node:crypto";
import contentType from "content-type";
import { TLSSocket } from "node:tls";
import getRawBody from "raw-body";

//#region src/sse/sse.ts
const MAXIMUM_MESSAGE_SIZE = "4mb";
/**
* Server transport for SSE: this will send messages over an SSE connection and receive messages from HTTP POST requests.
*
* This transport is only available in Node.js environments.
* @deprecated Use StreamableHTTPServerTransport from @modelcontextprotocol/server instead.
*/
var SSEServerTransport = class {
	_sseResponse;
	_sessionId;
	_options;
	onclose;
	onerror;
	onmessage;
	constructor(_endpoint, res, options) {
		this._endpoint = _endpoint;
		this.res = res;
		this._sessionId = randomUUID();
		this._options = options || { enableDnsRebindingProtection: false };
	}
	validateRequestHeaders(req) {
		if (!this._options.enableDnsRebindingProtection) return;
		if (this._options.allowedHosts && this._options.allowedHosts.length > 0) {
			const hostHeader = req.headers.host;
			if (!hostHeader || !this._options.allowedHosts.includes(hostHeader)) return `Invalid Host header: ${hostHeader}`;
		}
		if (this._options.allowedOrigins && this._options.allowedOrigins.length > 0) {
			const originHeader = req.headers.origin;
			if (originHeader && !this._options.allowedOrigins.includes(originHeader)) return `Invalid Origin header: ${originHeader}`;
		}
	}
	async start() {
		if (this._sseResponse) throw new Error("SSEServerTransport already started! If using Server class, note that connect() calls start() automatically.");
		this.res.writeHead(200, {
			"Content-Type": "text/event-stream",
			"Cache-Control": "no-cache, no-transform",
			Connection: "keep-alive"
		});
		const endpointUrl = new URL(this._endpoint, "http://localhost");
		endpointUrl.searchParams.set("sessionId", this._sessionId);
		const relativeUrlWithSession = endpointUrl.pathname + endpointUrl.search + endpointUrl.hash;
		this.res.write(`event: endpoint\ndata: ${relativeUrlWithSession}\n\n`);
		this._sseResponse = this.res;
		this.res.on("close", () => {
			this._sseResponse = void 0;
			this.onclose?.();
		});
	}
	async handlePostMessage(req, res, parsedBody) {
		if (!this._sseResponse) {
			const message = "SSE connection not established";
			res.writeHead(500).end(message);
			throw new Error(message);
		}
		const validationError = this.validateRequestHeaders(req);
		if (validationError) {
			res.writeHead(403).end(validationError);
			this.onerror?.(new Error(validationError));
			return;
		}
		const authInfo = req.auth;
		const host = req.headers.host;
		const protocol = req.socket instanceof TLSSocket ? "https" : "http";
		const fullUrl = host && req.url ? new URL(req.url, `${protocol}://${host}`) : void 0;
		const headers = new Headers();
		for (const [key, value] of Object.entries(req.headers)) if (typeof value === "string") headers.set(key, value);
		else if (Array.isArray(value)) for (const v of value) headers.append(key, v);
		const request = fullUrl ? new Request(fullUrl.toString(), {
			method: req.method ?? "POST",
			headers
		}) : void 0;
		let body;
		try {
			const ct = contentType.parse(req.headers["content-type"] ?? "");
			if (ct.type !== "application/json") throw new Error(`Unsupported content-type: ${ct.type}`);
			body = parsedBody ?? await getRawBody(req, {
				limit: MAXIMUM_MESSAGE_SIZE,
				encoding: ct.parameters.charset ?? "utf8"
			});
		} catch (error) {
			res.writeHead(400).end(String(error));
			this.onerror?.(error);
			return;
		}
		try {
			await this.handleMessage(typeof body === "string" ? JSON.parse(body) : body, {
				request,
				authInfo
			});
		} catch {
			res.writeHead(400).end(`Invalid message: ${body}`);
			return;
		}
		res.writeHead(202).end("Accepted");
	}
	async handleMessage(message, extra) {
		let parsedMessage;
		try {
			parsedMessage = JSONRPCMessageSchema.parse(message);
		} catch (error) {
			this.onerror?.(error);
			throw error;
		}
		this.onmessage?.(parsedMessage, extra);
	}
	async close() {
		this._sseResponse?.end();
		this._sseResponse = void 0;
		this.onclose?.();
	}
	async send(message, _options) {
		if (!this._sseResponse) throw new Error("Not connected");
		this._sseResponse.write(`event: message\ndata: ${JSON.stringify(message)}\n\n`);
	}
	get sessionId() {
		return this._sessionId;
	}
};

//#endregion
export { SSEServerTransport as t };
//# sourceMappingURL=sse-DqF0wITl.mjs.map