import { isPlainObject } from "es-toolkit"; import { resolveContentExpectations } from "./content"; import { CONTENT_EXTRACTOR_KEY_SET, MATCHER_KEY_SET } from "./keys"; import { isValueMatcherObject, isValueMatcherPrimitive, resolveValueExpectation } from "./value"; type ExpectRecord = Record; export function compactExpect(original: ExpectRecord, overrides: ExpectRecord): ExpectRecord { const result: ExpectRecord = {}; for (const [key, value] of Object.entries(original)) { if (value !== undefined) result[key] = value; } for (const [key, value] of Object.entries(overrides)) { if (value !== undefined) result[key] = value; } return result; } export function normalizeContent(value: unknown): unknown { if (value === undefined) return undefined; if (!Array.isArray(value)) return value; return (value as unknown[]).map((entry): unknown => { if (!canNormalizeContentEntry(entry)) return entry; const resolved = resolveContentExpectations([entry] as never); return resolved?.[0]; }); } export function normalizeKeyed(value: unknown): unknown { if (value === undefined) return undefined; if (!isPlainObject(value)) return value; return Object.entries(value as ExpectRecord).map(([key, item]) => ({ key, matcher: normalizeValue(item) })); } export function normalizeValue(value: unknown): unknown { if (value === undefined) return undefined; if (isValueMatcherPrimitive(value) || isValueMatcherObject(value)) return resolveValueExpectation(value); return value; } function canNormalizeContentEntry(value: unknown): boolean { if (!isPlainObject(value)) return false; const keys = Object.keys(value); const extractorKeys = keys.filter((key) => CONTENT_EXTRACTOR_KEY_SET.has(key)); const matcherKeys = keys.filter((key) => MATCHER_KEY_SET.has(key)); if (extractorKeys.length === 0) return matcherKeys.length > 0 && matcherKeys.length === keys.length; if (extractorKeys.length !== 1 || matcherKeys.length > 0 || keys.length !== 1) return false; return isPlainObject((value as ExpectRecord)[extractorKeys[0]!]); }