
      import { Temporal } from "@js-temporal/polyfill";
      import { URLPattern } from "urlpattern-polyfill";
      globalThis.addEventListener = () => {};
    
import { Application, Group, Organization, Person, Service, deno_default, getTypeId, lookupWebFinger } from "./lookup-Csp1y88W.js";
import { SpanStatusCode, trace } from "@opentelemetry/api";
import { domainToASCII, domainToUnicode } from "node:url";

//#region src/vocab/actor.ts
/**
* Checks if the given object is an {@link Actor}.
* @param object The object to check.
* @returns `true` if the given object is an {@link Actor}.
*/
function isActor(object) {
	return object instanceof Application || object instanceof Group || object instanceof Organization || object instanceof Person || object instanceof Service;
}
/**
* Gets the type name of the given actor.
* @param actor The actor to get the type name of.
* @returns The type name of the given actor.
*/
function getActorTypeName(actor) {
	if (actor instanceof Application) return "Application";
	else if (actor instanceof Group) return "Group";
	else if (actor instanceof Organization) return "Organization";
	else if (actor instanceof Person) return "Person";
	else if (actor instanceof Service) return "Service";
	throw new Error("Unknown actor type.");
}
/**
* Gets the actor class by the given type name.
* @param typeName The type name to get the actor class by.
* @returns The actor class by the given type name.
*/
function getActorClassByTypeName(typeName) {
	switch (typeName) {
		case "Application": return Application;
		case "Group": return Group;
		case "Organization": return Organization;
		case "Person": return Person;
		case "Service": return Service;
	}
	throw new Error("Unknown actor type name.");
}
/**
* Gets the actor handle, of the form `@username@domain`, from the given actor
* or an actor URI.
*
* @example
* ``` typescript
* // Get the handle of an actor object:
* await getActorHandle(
*   new Person({ id: new URL("https://fosstodon.org/users/hongminhee") })
* );
*
* // Get the handle of an actor URI:
* await getActorHandle(new URL("https://fosstodon.org/users/hongminhee"));
* ```
*
* @param actor The actor or actor URI to get the handle from.
* @param options The extra options for getting the actor handle.
* @returns The actor handle.  It starts with `@` and is followed by the
*          username and domain, separated by `@` by default (it can be
*          customized with the options).
* @throws {TypeError} If the actor does not have enough information to get the
*                     handle.
* @since 0.4.0
*/
async function getActorHandle(actor, options = {}) {
	const tracerProvider = options.tracerProvider ?? trace.getTracerProvider();
	const tracer = tracerProvider.getTracer(deno_default.name, deno_default.version);
	return await tracer.startActiveSpan("activitypub.get_actor_handle", async (span) => {
		if (isActor(actor)) {
			if (actor.id != null) span.setAttribute("activitypub.actor.id", actor.id.href);
			span.setAttribute("activitypub.actor.type", getTypeId(actor).href);
		}
		try {
			return await getActorHandleInternal(actor, options);
		} catch (error) {
			span.setStatus({
				code: SpanStatusCode.ERROR,
				message: String(error)
			});
			throw error;
		} finally {
			span.end();
		}
	});
}
async function getActorHandleInternal(actor, options = {}) {
	const actorId = actor instanceof URL ? actor : actor.id;
	if (actorId != null) {
		const result = await lookupWebFinger(actorId, {
			userAgent: options.userAgent,
			tracerProvider: options.tracerProvider
		});
		if (result != null) {
			const aliases = [...result.aliases ?? []];
			if (result.subject != null) aliases.unshift(result.subject);
			for (const alias of aliases) {
				const match = alias.match(/^acct:([^@]+)@([^@]+)$/);
				if (match != null) {
					const hostname = new URL(`https://${match[2]}/`).hostname;
					if (hostname !== actorId.hostname && !await verifyCrossOriginActorHandle(actorId.href, alias, options.userAgent, options.tracerProvider)) continue;
					return normalizeActorHandle(`@${match[1]}@${match[2]}`, options);
				}
			}
		}
	}
	if (!(actor instanceof URL) && actor.preferredUsername != null && actor.id != null) return normalizeActorHandle(`@${actor.preferredUsername}@${actor.id.host}`, options);
	throw new TypeError("Actor does not have enough information to get the handle.");
}
async function verifyCrossOriginActorHandle(actorId, alias, userAgent, tracerProvider) {
	const response = await lookupWebFinger(alias, {
		userAgent,
		tracerProvider
	});
	if (response == null) return false;
	for (const alias$1 of response.aliases ?? []) if (new URL(alias$1).href === actorId) return true;
	return false;
}
/**
* Normalizes the given actor handle.
* @param handle The full handle of the actor to normalize.
* @param options The options for normalizing the actor handle.
* @returns The normalized actor handle.
* @throws {TypeError} If the actor handle is invalid.
* @since 0.9.0
*/
function normalizeActorHandle(handle, options = {}) {
	handle = handle.replace(/^@/, "");
	const atPos = handle.indexOf("@");
	if (atPos < 1) throw new TypeError("Invalid actor handle.");
	let domain = handle.substring(atPos + 1);
	if (domain.length < 1 || domain.includes("@")) throw new TypeError("Invalid actor handle.");
	domain = domain.toLowerCase();
	domain = options.punycode ? domainToASCII(domain) : domainToUnicode(domain);
	domain = domain.toLowerCase();
	const user = handle.substring(0, atPos);
	return options.trimLeadingAt ? `${user}@${domain}` : `@${user}@${domain}`;
}

//#endregion
export { getActorClassByTypeName, getActorHandle, getActorTypeName, isActor, normalizeActorHandle };