//#region src/media/normalize.ts
const INTERNAL_MEDIA_PREFIX = "/_emdash/api/media/file/";
const URL_PATTERN = /^https?:\/\//;
/**
* Normalize a media field value into a consistent MediaValue shape.
*
* - `null`/`undefined` → `null`
* - Bare URL string → `{ provider: "external", id: "", src: url }`
* - Bare internal media URL → resolved via local provider's `get()`
* - Bare local media ID → resolved via local provider's `get()`
* - Object with `provider` + `id` → enriched with missing fields from provider
*/
async function normalizeMediaValue(value, getProvider) {
	if (value == null) return null;
	if (typeof value === "string") return normalizeStringUrl(value, getProvider);
	if (!isRecord(value)) return null;
	if (!("id" in value) && !("src" in value)) return null;
	const provider = (typeof value.provider === "string" ? value.provider : void 0) || "local";
	const id = typeof value.id === "string" ? value.id : "";
	if (provider === "external") return recordToMediaValue(value);
	const result = {
		...recordToMediaValue(value),
		provider
	};
	if (provider === "local") delete result.src;
	const needsDimensions = result.width == null || result.height == null;
	const needsStorageKey = provider === "local" && !result.meta?.storageKey;
	const needsFileInfo = !result.mimeType || !result.filename;
	const needsLqip = (result.mimeType ?? "").startsWith("image/") && (result.blurhash == null || result.dominantColor == null);
	if (!(needsDimensions || needsStorageKey || needsFileInfo || needsLqip) || !id) return result;
	const mediaProvider = getProvider(provider);
	if (!mediaProvider?.get) return result;
	let providerItem;
	try {
		providerItem = await mediaProvider.get(id);
	} catch {
		return result;
	}
	if (!providerItem) return result;
	return mergeProviderData(result, providerItem);
}
async function normalizeStringUrl(url, getProvider) {
	if (url.startsWith(INTERNAL_MEDIA_PREFIX)) return resolveInternalUrl(url, getProvider);
	if (URL_PATTERN.test(url)) return Promise.resolve({
		provider: "external",
		id: "",
		src: url
	});
	const localMedia = await resolveLocalId(url, getProvider);
	if (localMedia) return localMedia;
	return {
		provider: "external",
		id: "",
		src: url
	};
}
async function resolveInternalUrl(url, getProvider) {
	const storageKey = url.slice(24);
	const localProvider = getProvider("local");
	if (!localProvider?.get) return {
		provider: "external",
		id: "",
		src: url
	};
	let item;
	try {
		item = await localProvider.get(storageKey);
	} catch {
		return {
			provider: "external",
			id: "",
			src: url
		};
	}
	if (!item) return {
		provider: "external",
		id: "",
		src: url
	};
	return {
		provider: "local",
		id: item.id,
		filename: item.filename,
		mimeType: item.mimeType,
		width: item.width,
		height: item.height,
		blurhash: item.blurhash,
		dominantColor: item.dominantColor,
		alt: item.alt,
		meta: item.meta
	};
}
async function resolveLocalId(id, getProvider) {
	const localProvider = getProvider("local");
	if (!localProvider?.get) return null;
	let item;
	try {
		item = await localProvider.get(id);
	} catch {
		return null;
	}
	if (!item) return null;
	return {
		provider: "local",
		id: item.id,
		filename: item.filename,
		mimeType: item.mimeType,
		width: item.width,
		height: item.height,
		blurhash: item.blurhash,
		dominantColor: item.dominantColor,
		alt: item.alt,
		meta: item.meta
	};
}
/**
* Merge provider data into an existing MediaValue, preserving caller-supplied fields.
* Caller `alt` takes priority over provider `alt` (per-usage, not per-image).
*/
function mergeProviderData(existing, item) {
	const result = { ...existing };
	if (result.width == null && item.width != null) result.width = item.width;
	if (result.height == null && item.height != null) result.height = item.height;
	if (result.blurhash == null && item.blurhash != null) result.blurhash = item.blurhash;
	if (result.dominantColor == null && item.dominantColor != null) result.dominantColor = item.dominantColor;
	if (!result.filename && item.filename) result.filename = item.filename;
	if (!result.mimeType && item.mimeType) result.mimeType = item.mimeType;
	if (!result.alt && item.alt) result.alt = item.alt;
	if (item.meta) result.meta = {
		...item.meta,
		...result.meta
	};
	return result;
}
function isRecord(value) {
	return typeof value === "object" && value !== null && !Array.isArray(value);
}
/**
* Extract known MediaValue fields from a runtime-checked record.
* Avoids unsafe `as MediaValue` cast by reading each property explicitly.
*/
function recordToMediaValue(obj) {
	const result = { id: typeof obj.id === "string" ? obj.id : "" };
	if (typeof obj.provider === "string") result.provider = obj.provider;
	if (typeof obj.src === "string") result.src = obj.src;
	if (typeof obj.previewUrl === "string") result.previewUrl = obj.previewUrl;
	if (typeof obj.filename === "string") result.filename = obj.filename;
	if (typeof obj.mimeType === "string") result.mimeType = obj.mimeType;
	if (typeof obj.width === "number") result.width = obj.width;
	if (typeof obj.height === "number") result.height = obj.height;
	if (typeof obj.blurhash === "string") result.blurhash = obj.blurhash;
	if (typeof obj.dominantColor === "string") result.dominantColor = obj.dominantColor;
	if (typeof obj.alt === "string") result.alt = obj.alt;
	if (isRecord(obj.meta)) result.meta = obj.meta;
	return result;
}

//#endregion
export { normalizeMediaValue as n, INTERNAL_MEDIA_PREFIX as t };
//# sourceMappingURL=normalize-CeglrBT9.mjs.map