75 lines
3.4 KiB
JavaScript
75 lines
3.4 KiB
JavaScript
/**
|
||
* Parses an event by comparing old and new data to determine which fields have changed.
|
||
*
|
||
* This function analyzes the differences between previous (`oldData`) and current (`newData`)
|
||
* data states to identify changed fields. It determines if the event is a new entry or an update
|
||
* and returns details about changed fields, the event type, and associated metadata.
|
||
*
|
||
* @param {Object} options - Configuration options for parsing the event.
|
||
* @param {Object} [options.oldData] - The previous state of the data (undefined for new entries).
|
||
* @param {Object} options.newData - The current state of the data.
|
||
* @param {string} options.trigger - The type of event trigger (e.g., 'INSERT', 'UPDATE').
|
||
* @param {string} options.table - The name of the table associated with the event.
|
||
* @param {string} [options.jobId] - The job ID, if already extracted by the caller (optional).
|
||
* @returns {Object} An object containing the parsed event details:
|
||
* - {Array<string>} changedFieldNames - List of field names that have changed.
|
||
* - {Object} changedFields - Map of changed fields with their old and new values.
|
||
* - {boolean} isNew - True if the event is a new entry (no oldData provided).
|
||
* - {Object} data - The current data state (`newData`).
|
||
* - {string} trigger - The event trigger type.
|
||
* - {string} table - The table name.
|
||
* - {string|null} jobId - The provided jobId or null if not provided.
|
||
*/
|
||
const eventParser = async ({ oldData, newData, trigger, table, jobId = null }) => {
|
||
const isNew = !oldData; // True if no old data exists, indicating a new entry
|
||
let changedFields = {};
|
||
let changedFieldNames = [];
|
||
|
||
if (isNew) {
|
||
// For new entries, all fields in newData are considered "changed" (from undefined to their value)
|
||
changedFields = Object.fromEntries(
|
||
Object.entries(newData).map(([key, value]) => [key, { old: undefined, new: value }])
|
||
);
|
||
changedFieldNames = Object.keys(newData); // All keys are new
|
||
} else {
|
||
// Compare oldData and newData to detect updates
|
||
for (const key in newData) {
|
||
if (Object.prototype.hasOwnProperty.call(newData, key)) {
|
||
// Check if the field is new or its value has changed
|
||
if (
|
||
!Object.prototype.hasOwnProperty.call(oldData, key) || // Field didn’t exist before
|
||
JSON.stringify(oldData[key]) !== JSON.stringify(newData[key]) // Values differ (deep comparison)
|
||
) {
|
||
changedFields[key] = {
|
||
old: oldData[key], // Undefined if field wasn’t in oldData
|
||
new: newData[key]
|
||
};
|
||
changedFieldNames.push(key);
|
||
}
|
||
}
|
||
}
|
||
// Identify fields removed in newData (present in oldData but absent in newData)
|
||
for (const key in oldData) {
|
||
if (Object.prototype.hasOwnProperty.call(oldData, key) && !Object.prototype.hasOwnProperty.call(newData, key)) {
|
||
changedFields[key] = {
|
||
old: oldData[key],
|
||
new: null // Mark as removed
|
||
};
|
||
changedFieldNames.push(key);
|
||
}
|
||
}
|
||
}
|
||
|
||
return {
|
||
changedFieldNames, // Array of fields that changed
|
||
changedFields, // Object with old/new values for changed fields
|
||
isNew, // Boolean indicating if this is a new entry
|
||
data: newData, // Current data state
|
||
trigger, // Event trigger (e.g., 'INSERT', 'UPDATE')
|
||
table, // Associated table name
|
||
jobId // Provided jobId or null
|
||
};
|
||
};
|
||
|
||
module.exports = eventParser;
|