Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
(files, model) => {
const data = asArray(getDataPath(model, dataPath, () => null))
// Use flatten() as dataPath may contain wildcards, resulting in
// nested files arrays.
files.push(...flatten(data).filter(file => !!file))
return files
},
[]
const parent = getDataPath(cloned, parts)
delete parent[key]
}
// TODO: The model isn't necessarily fetched with data in the same order as
// `cloned` defines, e.g. if there is sorting in the database. A solid
// implementation of this would take care of that and map entries from
// `model` back to `cloned`, so that the `setDataPath` calls below would
// still work in such cases.
const model = await this.clone().upsertGraphAndFetch(cloned, options)
// Now for each identifier, create an object containing only the final id in
// the fetched model data:
const links = {}
for (const [identifier, path] of Object.entries(identifiers)) {
const { id } = getDataPath(model, path)
links[identifier] = { id }
}
// And finally replace all references with the final ids, before upserting
// once again:
for (const [path, reference] of Object.entries(references)) {
const link = links[reference]
if (link) {
setDataPath(model, path, link)
}
}
return model
}
export function getParentItem(rootItem, dataPath, isValue) {
const path = parseDataPath(dataPath)
if (path) {
// Remove the first path token if the path is not to an item's value:
if (isValue) path.pop()
// Remove the parent token. If it's a number, then we're dealing with an
// array and need to remove more tokens until we meet the actual parent:
let token
do {
token = path.pop()
} while (token != null && !isNaN(token))
// If the removed token is valid, we can get the parent data:
if (token != null) {
return getDataPath(rootItem, path)
}
}
return null
}
getSchemaValue(
keyOrDataPath,
{ type, default: def, schema = this.schema } = {}
) {
const types = type && asArray(type)
// For performance reasons, only support dataPaths in array format:
let value = schema
? isArray(keyOrDataPath)
? getDataPath(schema, keyOrDataPath, () => undefined)
: schema[keyOrDataPath]
: undefined
let params = null
const getParams = () => params || (params = getItemParams(this))
if (value === undefined && def !== undefined) {
if (isFunction(def) && !isMatchingType(types, def)) {
// Support `default()` functions for any type except `Function`:
def = def.call(this, getParams())
}
return def
}
if (isMatchingType(types, value)) {
return value
const { [uidProp]: id, [uidRefProp]: ref } = value
if (id) {
identifiers[id] = path.join('/')
} else if (ref) {
references[path.join('/')] = ref
}
}
})
// Now clone the data and delete all references from it, for the initial
// upsert.
const cloned = clone(data)
for (const path of Object.keys(references)) {
const parts = parseDataPath(path)
const key = parts.pop()
const parent = getDataPath(cloned, parts)
delete parent[key]
}
// TODO: The model isn't necessarily fetched with data in the same order as
// `cloned` defines, e.g. if there is sorting in the database. A solid
// implementation of this would take care of that and map entries from
// `model` back to `cloned`, so that the `setDataPath` calls below would
// still work in such cases.
const model = await this.clone().upsertGraphAndFetch(cloned, options)
// Now for each identifier, create an object containing only the final id in
// the fetched model data:
const links = {}
for (const [identifier, path] of Object.entries(identifiers)) {
const { id } = getDataPath(model, path)
links[identifier] = { id }
export function getItem(rootItem, dataPath, isValue) {
const path = parseDataPath(dataPath)
// Remove the first path token if the path is not to an item's value, and see
// if it's valid:
return path && (!isValue || path.pop() != null)
? getDataPath(rootItem, path)
: null
}