UNPKG

@directus/api

Version:

Directus is a real-time API and App dashboard for managing SQL database content

98 lines (96 loc) 5.01 kB
import { useEnv } from "@directus/env"; import { toArray } from "@directus/utils"; import { clone, isArray } from "lodash-es"; //#region src/database/run-ast/utils/merge-with-parent-items.ts function mergeWithParentItems(schema, nestedItem, parentItem, nestedNode, fieldAllowed) { const env = useEnv(); const nestedItems = toArray(nestedItem); const parentItems = clone(toArray(parentItem)); if (nestedNode.type === "m2o") { const parentsByForeignKey = /* @__PURE__ */ new Map(); const nestedPrimaryKeyField = schema.collections[nestedNode.relation.related_collection].primary; for (const parentItem$1 of parentItems) { const relationKey = parentItem$1[nestedNode.relation.field]?.[nestedPrimaryKeyField] ?? parentItem$1[nestedNode.relation.field]; if (!parentsByForeignKey.has(relationKey)) parentsByForeignKey.set(relationKey, []); parentItem$1[nestedNode.fieldKey] = null; parentsByForeignKey.get(relationKey).push(parentItem$1); } for (const nestedItem$1 of nestedItems) { const nestedPK = nestedItem$1[nestedPrimaryKeyField]; if (nestedPK === null) continue; if (!parentsByForeignKey.has(nestedPK)) continue; for (const parentItem$1 of parentsByForeignKey.get(nestedPK)) parentItem$1[nestedNode.fieldKey] = nestedItem$1; } } else if (nestedNode.type === "o2m") { const parentCollectionName = nestedNode.relation.related_collection; const parentPrimaryKeyField = schema.collections[parentCollectionName].primary; const parentRelationField = nestedNode.fieldKey; const nestedParentKeyField = nestedNode.relation.field; const parentsByPrimaryKey = /* @__PURE__ */ new Map(); for (const parentItem$1 of parentItems) { if (!parentItem$1[parentRelationField]) parentItem$1[parentRelationField] = []; let parentPrimaryKey = parentItem$1[parentPrimaryKeyField]; if (parentPrimaryKey === null) continue; else parentPrimaryKey = parentPrimaryKey.toString(); if (parentsByPrimaryKey.has(parentPrimaryKey)) throw new Error(`Duplicate parent primary key '${parentPrimaryKey}' of '${parentCollectionName}' when merging o2m nested items`); parentsByPrimaryKey.set(parentPrimaryKey, parentItem$1); } const toAddToAllParents = []; for (const nestedItem$1 of nestedItems) { if (nestedItem$1 === null) continue; if (Array.isArray(nestedItem$1[nestedParentKeyField])) { toAddToAllParents.push(nestedItem$1); continue; } const parentPrimaryKey = nestedItem$1[nestedParentKeyField]?.[parentPrimaryKeyField] ?? nestedItem$1[nestedParentKeyField]; if (parentPrimaryKey === null) continue; const parentItem$1 = parentsByPrimaryKey.get(parentPrimaryKey.toString()); if (!parentItem$1) continue; parentItem$1[parentRelationField].push(nestedItem$1); } for (const [index, parentItem$1] of parentItems.entries()) { if (fieldAllowed === false || isArray(fieldAllowed) && !fieldAllowed[index]) { parentItem$1[nestedNode.fieldKey] = null; continue; } parentItem$1[parentRelationField].push(...toAddToAllParents); const limit = nestedNode.query.limit ?? Number(env["QUERY_LIMIT_DEFAULT"]); if (nestedNode.query.page && nestedNode.query.page > 1) parentItem$1[nestedNode.fieldKey] = parentItem$1[nestedNode.fieldKey].slice(limit * (nestedNode.query.page - 1)); if (nestedNode.query.offset && nestedNode.query.offset >= 0) parentItem$1[nestedNode.fieldKey] = parentItem$1[nestedNode.fieldKey].slice(nestedNode.query.offset); if (limit !== -1) parentItem$1[nestedNode.fieldKey] = parentItem$1[nestedNode.fieldKey].slice(0, limit); parentItem$1[nestedNode.fieldKey] = parentItem$1[nestedNode.fieldKey].sort((a, b) => { const sortField = nestedNode.query.sort[0]; let column = sortField; let order = "asc"; if (sortField.startsWith("-")) { column = sortField.substring(1); order = "desc"; } if (a[column] === b[column]) return 0; if (a[column] === null) return 1; if (b[column] === null) return -1; if (order === "asc") return a[column] < b[column] ? -1 : 1; else return a[column] < b[column] ? 1 : -1; }); } } else if (nestedNode.type === "a2o") for (const parentItem$1 of parentItems) { if (!nestedNode.relation.meta?.one_collection_field) { parentItem$1[nestedNode.fieldKey] = null; continue; } const relatedCollection = parentItem$1[nestedNode.relation.meta.one_collection_field]; if (!nestedItem[relatedCollection]) { parentItem$1[nestedNode.fieldKey] = null; continue; } const relatedPrimaryKeyField = schema.collections[relatedCollection].primary; const foreignKey = parentItem$1[nestedNode.relation.field]?.[relatedPrimaryKeyField] ?? parentItem$1[nestedNode.relation.field]; const itemChild = nestedItem[relatedCollection].find((nestedItem$1) => { return nestedItem$1[nestedNode.relatedKey[relatedCollection]] == foreignKey; }); parentItem$1[nestedNode.fieldKey] = itemChild || null; } return Array.isArray(parentItem) ? parentItems : parentItems[0]; } //#endregion export { mergeWithParentItems };