Source

utils/step-conversion.utils.js

/**
 * Step and Object Conversion Utilities
 *
 * This file contains utility functions for converting between different formats
 * used in the investigation system, including steps and objects.
 */
/**
 * Convert database steps (IStep[]) to simple steps (ISimpleStep[]) for API response
 * @category Utils
 * @param {IInvestigationBaseStepModel[]} steps - Database steps with EditableField structure
 * @returns {IStep[]} - Simple steps for API response with empty strings instead of undefined
 */
export function convertStepsToSimple(steps) {
    return steps.map((step) => ({
        title: step.title?.value || "",
        desiredOutcome: step.desiredOutcome?.value || "",
        alternativeOutcome: step.alternativeOutcome?.value || "",
        descriptionEn: step.descriptionEn?.value || "",
        skippable: step.skippable?.value || null,
        skippable_after_marking: step.skippable_after_marking?.value || null,
    }));
}
/**
 * Converts an array of `IObjectBase` objects with `EditableField` structures
 * into a plain input format suitable for API requests or other processing.
 *
 * Extracts the `value` from each editable field and provides default fallbacks:
 * - Empty string for `name` and `objectId`
 * - `0` for position and rotation coordinates
 * - `null` for size if not defined
 * @category Utils
 * @param {IObjectBase[]} objects - Array of objects with `EditableField` properties.
 * @param {boolean} withCoordinates - If true, it converts with coordinates fields(position, rotation, size), otherwise converts without them.
 * @returns {object[]} - Array of plain objects with `name`, `objectId`, `position`, `rotation`, and `size`.
 */
export function convertObjectsToInputFormat(objects, withCoordinates = true) {
    return objects.map((object) => {
        if (withCoordinates) {
            return {
                name: object.name?.value || "",
                objectId: object.objectId?.value || "",
                position: object.position
                    ? {
                        x: object.position.x?.value || 0,
                        y: object.position.y?.value || 0,
                        z: object.position.z?.value || 0,
                    }
                    : null,
                rotation: object.rotation
                    ? {
                        x: object.rotation.x?.value || 0,
                        y: object.rotation.y?.value || 0,
                        z: object.rotation.z?.value || 0,
                    }
                    : null,
                size: object?.size?.value || null,
            };
        }
        else {
            return {
                name: object.name?.value || "",
                objectId: object.objectId?.value || "",
            };
        }
    });
}
/**
 * Convert database objects (IObject[]) to simple objects (ISimpleObject[]) for API response
 * @category Utils
 * @param {IObjectBase[]} objects - Database objects with EditableField structure
 * @returns {object[]} - Simple objects for API response with default values instead of null/undefined
 */
export function convertObjectsToSimple(objects) {
    return objects.map((object) => {
        return {
            name: {
                value: object.name?.value || "",
                isContradicting: object.name?.isContradicting || "",
                contradictionReason: object.name?.contradictionReason || "",
                targetFieldName: object.name?.targetFieldName || null,
            },
            objectId: {
                value: object.objectId?.value || "",
                isContradicting: object.name?.isContradicting || "",
                contradictionReason: object.name?.contradictionReason || "",
                targetFieldName: object.name?.targetFieldName || null,
            },
            position: object.position
                ? {
                    x: object.position.x?.value || 0,
                    y: object.position.y?.value || 0,
                    z: object.position.z?.value || 0,
                }
                : null,
            rotation: object.rotation
                ? {
                    x: object.rotation.x?.value || 0,
                    y: object.rotation.y?.value || 0,
                    z: object.rotation.z?.value || 0,
                }
                : null,
            size: object?.size?.value || null,
        };
    });
}
/**
 * Converts an array of simple objects (from AI response or plain format) to IUpdateObjectDto format.
 * This is the reverse of convertObjectsToInputFormat - it converts from simple format to update DTO format.
 * @category Utils
 * @param {ISimpleObject[] | ISimpleResponseObject[]} objects - Array of simple objects with plain values.
 * @returns {IUpdateObjectDto[]} - Array of objects in IUpdateObjectDto format suitable for update requests.
 */
export function convertObjectsToUpdateFormat(objects) {
    return objects
        .filter((obj) => obj && typeof obj === "object")
        .map((obj) => {
        const updateObj = {
            name: obj.name ? { value: String(obj.name) } : undefined,
            objectId: obj.objectId || obj.name ? { value: String(obj.objectId || obj.name || "") } : undefined,
            position: obj.position && typeof obj.position === "object"
                ? {
                    x: Number(obj.position.x) || 0,
                    y: Number(obj.position.y) || 0,
                    z: Number(obj.position.z) || 0,
                }
                : undefined,
            rotation: obj.rotation && typeof obj.rotation === "object"
                ? {
                    x: Number(obj.rotation.x) || 0,
                    y: Number(obj.rotation.y) || 0,
                    z: Number(obj.rotation.z) || 0,
                }
                : undefined,
            size: obj.size ? Number(obj.size) : 1,
        };
        return updateObj;
    });
}
/**
 * Creates a helper function to extract a simplified version of an `EditableField`
 * from an investigation object.
 *
 * The returned function allows retrieving a specific field by name and converts it into
 * a plain `IEditableFieldSimple` object, providing default values for missing properties.
 * @category Utils
 * @param {IInvestigation} investigation - The investigation object containing `EditableField` properties.
 * @returns {Function} - A function that accepts:
 *   - `fieldName`: The key of the field to extract.
 *   - `defaultValue`: The fallback value if the field's value is missing (default: "").
 *   Returns `IEditableFieldSimple` or `null` if the field does not exist.
 */
export function convertEditableFieldToSimple(investigation) {
    return (fieldName, defaultValue = "") => {
        const field = investigation[fieldName];
        return field
            ? {
                value: field.value || defaultValue,
                isContradicting: field.isContradicting || false,
                targetFieldName: field.targetFieldName || null,
                contradictionReason: field.contradictionReason || null,
            }
            : null;
    };
}