UNPKG

@absolute/change-tracker-node-sdk

Version:

ChangeTracker SDK for Node.js

114 lines (88 loc) 4.42 kB
const {Field, Row, RowStatus, Table} = require('../models') /** * diff - produces a new Row which contains the differences between prev and next model * @param {Row} prev - model before change * @param {Row} next - model after change * @returns {Row} a Row that contains differences between prev and next **/ function diff(prev, next) { const diffModel = new Row(); const prevIsValid = isValidModel(prev); const nextIsValid = isValidModel(next); if (prevIsValid) diffModel.key = prev.key; if (!prevIsValid && nextIsValid) diffModel.key = next.key; if (!prevIsValid && !nextIsValid) { console.error('ChangeTracker, diff: missing or invalid diff models'); return null; } if (!nextIsValid) diffModel.state = RowStatus.Deleted; if (!prevIsValid) diffModel.state = RowStatus.New; if (prevIsValid) for (let field of prev.fields) { //ignore default field values ('', null, undefined) if (diffModel.state === RowStatus.Deleted && isDefaultValue(field.prevValue)) continue; const diffField = new Field(field.name, field.prevValue) diffModel.fields.push(diffField); } if (nextIsValid) { for (let field of next.fields) { //ignore default field values ('', null, undefined) if (diffModel.state === RowStatus.New && isDefaultValue(field.prevValue)) continue; let diffField = diffModel.fields.find(el => (el.name + '').toLowerCase() === (field.name + '').toLowerCase()); if (!diffField) { diffField = new Field(field.name, undefined, field.prevValue); diffModel.fields.push(diffField); } else diffField.nextValue = field.prevValue; } } // Prende solo quelli differenti diffModel.fields = diffModel.fields.filter(el => (el.prevValue + '').toLowerCase() !== (el.nextValue + '').toLowerCase()); if (!diffModel.state) diffModel.state = diffModel.fields.length > 0 ? RowStatus.Modified : RowStatus.Unchanged; if (prev && Array.isArray(prev.tables) && prev.tables.length > 0) for (let table of prev.tables) { const addedTable = new Table(table.name); diffModel.tables.push(addedTable); for (let row of table.rows) { const nextTable = next && Array.isArray(next.tables) && next.tables.find(el => (el.name + '') === (table.name + '')); const nextRow = nextTable && Array.isArray(nextTable.rows) && nextTable.rows.find(el => el.key === row.key); const diffRow = diff(row, nextRow); if (diffRow && isFull(diffRow)) addedTable.rows.push(diffRow); } } if (next && Array.isArray(next.tables) && next.tables.length > 0) for (let table of next.tables) { let addedTable = diffModel.tables.find(el => el.name === table.name); if (!addedTable) { addedTable = new Table(table.name); diffModel.tables.push(addedTable); } for (let row of table.rows) { const prevTable = prev && Array.isArray(prev.tables) && prev.tables.find(el => (el.name + '') === (table.name + '')); const prevRow = prevTable && Array.isArray(prevTable.rows) && prevTable.rows.find(el => el.key === row.key); const diffRow = diff(prevRow, row); const alreadyRow = addedTable.rows.find(el => el.key === row.key); if (!alreadyRow && diffRow && isFull(diffRow)) addedTable.rows.push(diffRow); } } diffModel.tables = diffModel.tables.filter(el => Array.isArray(el.rows) && el.rows.length > 0); return diffModel; } function isValidModel(row) { return typeof row === 'object' && row != null && row instanceof Row; } function isDefaultValue(value) { return typeof value === 'undefined' || value === null || value === ''; } function isFull(model) { return Array.isArray(model.fields) && model.fields.length > 0 || Array.isArray(model.tables) && model.tables.some(el => el.rows.some(isFull)); } module.exports = {diff}