/**
* DTO Utility Functions
*
* Helper functions for converting database models to DTOs.
*/
/** Default number of history entries to return */
export const DEFAULT_HISTORY_LIMIT = 2;
/**
* Maps history entries to response format
* @template T - The type of the history entry value
* @param {Array<IHistoryEntry<T>> | undefined} history - Array of history entries to map
* @param {number} limit - Maximum number of history entries to return
* @returns {IFieldHistoryEntryResponse[] | undefined} Mapped history entries or undefined if no history
*/
export function mapHistoryEntries(history, limit = DEFAULT_HISTORY_LIMIT) {
if (!history)
return undefined;
return history.slice(0, limit).map((entry) => ({
value: entry.value,
updatedBy: entry.updatedBy?.toString() || null,
updatedAt: entry.updatedAt,
}));
}
/**
* Creates an empty editable field response with default value
* @template T - The type of the field value
* @param {T} defaultValue - The default value to use for the empty field
* @returns {IEditableFieldResponse<T>} Empty editable field response with the default value
*/
export function createEmptyEditableField(defaultValue) {
return {
value: defaultValue,
originalValue: null,
isContradicting: false,
targetFieldName: null,
contradictionReason: null,
history: undefined,
};
}
/**
* Convert editable field to response DTO format
* @template T - The type of the field value
* @param {IEditableField<T> | null | undefined} field - The editable field to convert
* @param {T} defaultValue - The default value to use if the field is null or undefined
* @param {number} historyLimit - Maximum number of history entries to return
* @returns {IEditableFieldResponse<T>} The formatted editable field response
*/
export function fromEditableField(field, defaultValue, historyLimit = DEFAULT_HISTORY_LIMIT) {
return {
value: field?.value ?? defaultValue,
originalValue: field?.aiGeneratedValue ?? null,
isContradicting: field?.isContradicting ?? false,
targetFieldName: field?.targetFieldName ?? null,
contradictionReason: field?.contradictionReason ?? null,
history: mapHistoryEntries(field?.history, historyLimit),
};
}
/**
* Returns either an empty field or converts from editable field based on condition
* @template T - The type of the field value
* @param {boolean} shouldBeEmpty - Whether to return an empty field
* @param {IEditableField<T> | null | undefined} field - The editable field to convert if not empty
* @param {T} defaultValue - The default value to use
* @param {number} historyLimit - Maximum number of history entries to return
* @returns {IEditableFieldResponse<T>} Empty or populated editable field response
*/
export function getFieldOrEmpty(shouldBeEmpty, field, defaultValue, historyLimit = DEFAULT_HISTORY_LIMIT) {
return shouldBeEmpty
? createEmptyEditableField(defaultValue)
: fromEditableField(field, defaultValue, historyLimit);
}
/**
* Maps Vector3 history (x, y, z) to response format
* @param {IVector3Editable | undefined} vector - Vector3 object with x, y, z editable fields
* @param {number} limit - Maximum number of history entries per axis
* @returns {IVector3HistoryResponse | undefined} Object with x, y, z history arrays or undefined if no vector
*/
export function mapVector3History(vector, limit = DEFAULT_HISTORY_LIMIT) {
if (!vector)
return undefined;
return {
x: mapHistoryEntries(vector.x?.history, limit),
y: mapHistoryEntries(vector.y?.history, limit),
z: mapHistoryEntries(vector.z?.history, limit),
};
}
Source