import { defineMetadata, getMetadata } from "muddle/metadata"; export const HYDRATE_METADATA_KEY = "muddle:orm:hydrated"; export interface HydrateOptions { /** Computes the value from the raw database row. */ decode?: (row: Record) => Value; /** Column the value is derived from, handed to `decode` as second argument. */ column?: string; } export interface HydrateDescriptor { property: string; options: HydrateOptions; } /** Declares a hydrated (computed) property. */ export function Hydrate( options: HydrateOptions = {}, ): PropertyDecorator { return (target, propertyKey) => { const constructor = target.constructor as object; const hydrated = getHydratedProperties(constructor); hydrated.set(String(propertyKey), { property: String(propertyKey), options: options as HydrateOptions, }); }; } /** Reads the hydrated properties declared on a model class. */ export function getHydratedProperties( target: object, ): Map { const existing = getMetadata(HYDRATE_METADATA_KEY, target) as | Map | undefined; if (existing) return existing; const hydrated = new Map(); defineMetadata(HYDRATE_METADATA_KEY, hydrated, target); return hydrated; }