export interface HasCustomFields { /** * Points at the schema in `erpCustomFieldsSchemas` that should validate `customFields`. * Omit (undefined) to avoid unintentionally overwriting existing server-side values. */ customFieldsSchemaRef?: number | null; /** * Schema-bound custom fields stored on the ERP entity. * Omit (undefined) to avoid unintentionally overwriting existing server-side values. */ customFields?: Record | null; } /** * Apply `customFields` and `customFieldsSchemaRef` to an outgoing API payload. * * IMPORTANT: We only set fields when they are not `undefined` (null is allowed) to avoid * unintended overwrites when callers don't specify custom fields. */ export function applyCustomFields>( obj: T, customFields: Pick ): T { const out = obj as Record; if (customFields.customFieldsSchemaRef !== undefined) { out["customFieldsSchemaRef"] = customFields.customFieldsSchemaRef; } if (customFields.customFields !== undefined) { out["customFields"] = customFields.customFields; } return obj; } /** * Convenience helper to construct a "full" API payload from a REST-style payload. */ export function toFullApiObjectFromRest( restObj: Record, source: HasCustomFields ): Record { return applyCustomFields(restObj, source); } /** * Merge non-empty `customFields` into a REST payload. Returns a shallow copy so callers can * keep a strict `Record` base type before widening with optional `customFields`. */ export function applyNonEmptyCustomFieldsToRest>( obj: T, customFields: Record | null | undefined ): T & { customFields?: Record } { if (customFields != null && Object.keys(customFields).length > 0) { return { ...obj, customFields }; } return obj as T & { customFields?: Record }; }