function serializeFieldValue()

in packages/webhook-triggers-app/src/workflows/workflow-field-changes.js [10:121]


function serializeFieldValue(value) {
    if (value === null || value === undefined) {
        return null;
    }

    // Primitives - return as is
    if (typeof value === 'number' || typeof value === 'boolean') {
        return value;
    }

    // Strings - return as is
    if (typeof value === 'string') {
        return value;
    }

    // Handle YouTrack entity objects (User, State, Priority, EnumBundleElement, etc.)
    if (typeof value === 'object') {
        // User objects - check for login OR $$type === 'User'
        if (value.login !== undefined || value.$$type === 'User') {
            return {
                login: value.login || null,
                fullName: value.fullName || null,
                email: value.email || null
            };
        }

        // Enum/State/Priority objects have name and/or presentation
        if (value.name !== undefined || value.presentation !== undefined) {
            return {
                name: value.name || null,
                presentation: value.presentation || value.name || null
            };
        }

        // Period/Duration objects (Joda-Time Period)
        if (typeof value.getMinutes === 'function' && typeof value.getHours === 'function') {
            const hourDuration = 60;
            const dayDuration = 8;
            const weekDuration = 5;
            const minutes = value.getMinutes() || 0;
            const hours = value.getHours() || 0;
            const days = typeof value.getDays === 'function' ? (value.getDays() || 0) : 0;
            const weeks = typeof value.getWeeks === 'function' ? (value.getWeeks() || 0) : 0;
            const totalMinutes = minutes +
                (hours * hourDuration) +
                (days * dayDuration * hourDuration) +
                (weeks * weekDuration * dayDuration * hourDuration);
            return {
                minutes: totalMinutes,
                presentation: value.toString ? value.toString() : (totalMinutes + 'm')
            };
        }

        // Period objects with minutes property (fallback)
        if (value.minutes !== undefined) {
            return {
                minutes: value.minutes,
                presentation: null
            };
        }

        // Date fields (check for getTime method)
        if (typeof value.getTime === 'function') {
            return value.getTime();
        }

        // Arrays (multi-value fields like tags, versions)
        if (Array.isArray(value) || typeof value.forEach === 'function') {
            const result = [];
            value.forEach(function (item) {
                result.push(serializeFieldValue(item));
            });
            return result;
        }

        // For any other object, try to extract id and name safely
        try {
            const serialized = {};
            if (value.id !== undefined) {
                serialized.id = value.id;
            }
            if (value.name !== undefined) {
                serialized.name = value.name;
            }
            if (value.presentation !== undefined) {
                serialized.presentation = value.presentation;
            }
            if (Object.keys(serialized).length > 0) {
                return serialized;
            }
        } catch {
            // Ignore errors from accessing properties
        }
    }

    // Final fallback: try presentation, name, or return null
    try {
        if (value.presentation) {
            return value.presentation;
        }
        if (value.name) {
            return value.name;
        }
        if (value.visibleName) {
            return value.visibleName;
        }
    } catch {
        // Ignore
    }

    return null;
}