mirror of
https://github.com/hcengineering/platform.git
synced 2025-02-12 05:42:31 +00:00
45 lines
1.5 KiB
TypeScript
45 lines
1.5 KiB
TypeScript
![]() |
import { Class, Data, Doc, DocumentUpdate, Ref, Space, TxOperations } from '@anticrm/core'
|
||
|
import { deepEqual } from 'fast-equals'
|
||
|
|
||
|
function toUndef (value: any): any {
|
||
|
return value === null ? undefined : value
|
||
|
}
|
||
|
|
||
|
function diffAttributes (doc: Data<Doc>, newDoc: Data<Doc>): DocumentUpdate<Doc> {
|
||
|
const result: DocumentUpdate<any> = {}
|
||
|
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
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @public
|
||
|
*/
|
||
|
export async function createOrUpdate<T extends Doc> (client: TxOperations, _class: Ref<Class<T>>, space: Ref<Space>, data: Data<T>, _id: Ref<T>): Promise<void> {
|
||
|
const existingDoc = await client.findOne<Doc>(_class, { _id })
|
||
|
if (existingDoc !== undefined) {
|
||
|
const { _class: _oldClass, _id, space: _oldSpace, modifiedBy, modifiedOn, ...oldData } = existingDoc
|
||
|
const updateOp = diffAttributes(oldData, data)
|
||
|
if (Object.keys(updateOp).length > 0) {
|
||
|
await client.update(existingDoc, updateOp)
|
||
|
}
|
||
|
} else {
|
||
|
await client.createDoc<T>(_class, space, data, _id)
|
||
|
}
|
||
|
}
|