/* RFC-0042 shared utilities for section components — NEED_THIS_* markers and type casting. Do not implement content fetching — RFC-0042 removed stub-based loading. Do not handle i18n logic — lang is passed separately via SectionProps. RFC-0042: Created shared utilities to centralize NEED_THIS_* pattern and type casting. */ /** * [RFC-0042] Helper for NEED_THIS_* markers — shows explicit placeholder when field is missing. * Use this in section components to indicate required fields that were not provided in blocks[].props. * * @param fieldName - The name of the field (will be uppercased in the marker) * @param value - The value from pageOverride.props * @returns The value if present and non-empty, otherwise `NEED_THIS_${fieldName.toUpperCase()}` * * @example * ```typescript * const content = { * heading: need("heading", props.heading), * description: need("description", props.description), * }; * ``` */ export function need(fieldName: string, value: T | undefined | null): T | string { if (value === undefined || value === null) { return `NEED_THIS_${fieldName.toUpperCase()}`; } if (typeof value === "string") { return value.trim() !== "" ? value : `NEED_THIS_${fieldName.toUpperCase()}`; } if (Array.isArray(value)) { return value.length > 0 ? value : (`NEED_THIS_${fieldName.toUpperCase()}` as unknown as T); } if (typeof value === "object") { return Object.keys(value as object).length > 0 ? value : (`NEED_THIS_${fieldName.toUpperCase()}` as unknown as T); } return value; } /** * [RFC-0042] Type-safe casting function for pageOverride to section content types. * Use this instead of `as unknown as T` to make type casting explicit and searchable. * * @ai-invariant Use this function when casting pageOverride to a specific section content type. * * @param pageOverride - The pageOverride from SectionProps (blocks[].props) * @returns The same object cast to type T * * @example * ```typescript * const props = cast(pageOverride); * ``` */ export function cast(pageOverride: Record): T { return pageOverride as unknown as T; } /** * [RFC-0042] Default value helper with NEED_THIS_* marker fallback. * Returns the value if present, otherwise returns the provided default or a NEED_THIS marker. * * @param value - The value from pageOverride.props * @param defaultValue - Default value to use if value is missing * @param fieldName - Field name for NEED_THIS marker (only used if defaultValue is not provided) * @returns The value, defaultValue, or NEED_THIS marker * * @example * ```typescript * const content = { * texture: withDefault(props.texture, false), * heading: withDefault(props.heading, null, "heading"), // becomes NEED_THIS_HEADING if missing * }; * ``` */ export function withDefault( value: T | undefined, defaultValue: T | null, fieldName?: string, ): T | string { if (value !== undefined && value !== null) { return value; } if (defaultValue !== null) { return defaultValue; } return fieldName ? `NEED_THIS_${fieldName.toUpperCase()}` : "NEED_THIS_VALUE"; }