mirror of
https://github.com/hcengineering/platform.git
synced 2025-02-09 04:18:33 +00:00
82 lines
2.0 KiB
TypeScript
82 lines
2.0 KiB
TypeScript
import { PlatformError, Severity, Status } from '@hcengineering/platform'
|
|
import { Doc } from './classes'
|
|
import core from './component'
|
|
import justClone from 'just-clone'
|
|
|
|
/**
|
|
* @public
|
|
*/
|
|
export function getObjectValue (key: string, doc: Doc): any {
|
|
// Check dot notation
|
|
if (key.length === 0) {
|
|
return doc
|
|
}
|
|
key = key.split('\\$').join('$')
|
|
const dots = key.split('.')
|
|
// Replace escapting, since memdb is not escape keys
|
|
|
|
// We have dots, so iterate in depth
|
|
let pos = 0
|
|
let value = doc as any
|
|
for (const d of dots) {
|
|
if (Array.isArray(value) && isNestedArrayQuery(value, d)) {
|
|
// Array and d is not an indexed field.
|
|
// So return array of nested values.
|
|
return getNestedArrayValue(value, dots.slice(pos).join('.'))
|
|
}
|
|
value = value?.[d]
|
|
pos++
|
|
}
|
|
return value
|
|
}
|
|
|
|
/**
|
|
* @public
|
|
*/
|
|
export function setObjectValue (key: string, doc: Doc, newValue: any): void {
|
|
// Check dot notation
|
|
if (key.length === 0) {
|
|
return
|
|
}
|
|
key = key.split('\\$').join('$')
|
|
let dots = key.split('.')
|
|
// Replace escapting, since memdb is not escape keys
|
|
|
|
const last = dots[dots.length - 1]
|
|
dots = dots.slice(0, -1)
|
|
|
|
// We have dots, so iterate in depth
|
|
let value = doc as any
|
|
for (const d of dots) {
|
|
if (Array.isArray(value) && isNestedArrayQuery(value, d)) {
|
|
// Arrays are not supported
|
|
throw new PlatformError(new Status(Severity.ERROR, core.status.ObjectNotFound, { _id: 'dots' }))
|
|
}
|
|
const lvalue = value?.[d]
|
|
if (lvalue === undefined) {
|
|
value[d] = {}
|
|
value = value?.[d]
|
|
} else {
|
|
value = lvalue
|
|
}
|
|
}
|
|
value[last] = justClone(newValue)
|
|
return value
|
|
}
|
|
|
|
function isNestedArrayQuery (value: any, d: string): boolean {
|
|
return Number.isNaN(Number.parseInt(d)) && value?.[d as any] === undefined
|
|
}
|
|
|
|
function getNestedArrayValue (value: any[], name: string): any[] {
|
|
const result = []
|
|
for (const v of value) {
|
|
result.push(...arrayOrValue(getObjectValue(name, v)))
|
|
}
|
|
return result
|
|
}
|
|
|
|
function arrayOrValue (vv: any): any[] {
|
|
return Array.isArray(vv) ? vv : [vv]
|
|
}
|