import { Class, Data, Doc, DocumentUpdate, Ref, Space, TxOperations } from '@hcengineering/core' import { deepEqual } from 'fast-equals' function toUndef (value: any): any { return value === null ? undefined : value } function diffAttributes (doc: Data, newDoc: Data): DocumentUpdate { const result: DocumentUpdate = {} const allDocuments = new Map(Object.entries(doc)) const newDocuments = new Map(Object.entries(newDoc)) for (const [key, value] of allDocuments) { const newValue = toUndef(newDocuments.get(key)) if (!deepEqual(newValue, toUndef(value))) { // update is required, since values are different result[key] = newValue } } for (const [key, value] of newDocuments) { const oldValue = toUndef(allDocuments.get(key)) if (oldValue === undefined && value !== undefined) { // Update with new value. result[key] = value } } return result } /** * Create or update document if modified only by system account. * @public */ export async function createOrUpdate ( client: TxOperations, _class: Ref>, space: Ref, data: Data, _id: Ref ): Promise { const existingDoc = await client.findOne(_class, { _id }) if (existingDoc !== undefined) { const { _class: _oldClass, _id, space: _oldSpace, modifiedBy, modifiedOn, ...oldData } = existingDoc if (modifiedBy === client.txFactory.account) { const updateOp = diffAttributes(oldData, data) if (Object.keys(updateOp).length > 0) { await client.update(existingDoc, updateOp) } } } else { await client.createDoc(_class, space, data, _id) } } /** * @public */ export interface ModelLogger { log: (...data: any[]) => void } /** * @public */ export const consoleModelLogger: ModelLogger = { log (...data: any[]): void { console.log(...data) } }