import _ from 'lodash'; import { ContentStoreTypes } from '../index'; import type { ReferencedItem, ReferenceMap } from '../types/'; export const getReferenceMap = (documents: (ContentStoreTypes.Document | ContentStoreTypes.APIDocumentObject | ContentStoreTypes.Asset)[]): ReferenceMap => { const referenceMap: ReferenceMap = {}; const iterateFields = ( fields: Record, rootObject: ContentStoreTypes.Document | ContentStoreTypes.APIDocumentObject | ContentStoreTypes.Asset ) => { for (const fieldName in fields) { const field = fields[fieldName]; if (field) { iterateField(field, rootObject); } } }; const iterateField = ( field: ContentStoreTypes.DocumentField | ContentStoreTypes.DocumentFieldAPI | ContentStoreTypes.AssetFileField, rootObject: ContentStoreTypes.Document | ContentStoreTypes.APIDocumentObject | ContentStoreTypes.Asset ) => { if (field.type === 'reference' || field.type === 'unresolved_reference' || field.type === 'cross-reference') { let references: { srcType: string; srcProjectId: string; srcDocumentId: string }[] = []; if (field.type === 'unresolved_reference') { if ('refId' in field) { references = [ { srcType: rootObject.srcType, srcProjectId: rootObject.srcProjectId, srcDocumentId: field.refId } ]; } } else if (field.type === 'reference') { if ('locales' in field) { references = _.values(field.locales).map((ref) => ({ srcType: rootObject.srcType, srcProjectId: rootObject.srcProjectId, srcDocumentId: ref.refId })); } else if (!field.isUnset) { references = [ { srcType: rootObject.srcType, srcProjectId: rootObject.srcProjectId, srcDocumentId: field.refId } ]; } } else { if ('locales' in field) { references = _.values(field.locales).map((ref) => ({ srcType: ref.refSrcType, srcProjectId: ref.refProjectId, srcDocumentId: ref.refId })); } else if ('refId' in field) { references = [ { srcType: field.refSrcType, srcProjectId: field.refProjectId, srcDocumentId: field.refId } ]; } } for (const reference of references) { const currentObjectPath = [reference.srcType, reference.srcProjectId, reference.srcDocumentId]; const currentReferences: ReferencedItem[] = _.get(referenceMap, currentObjectPath) || []; const existingDef = currentReferences.find( (ref) => ref.srcType === rootObject.srcType && ref.srcProjectId === rootObject.srcProjectId && ref.srcDocumentId === rootObject.srcObjectId ); if (existingDef) { existingDef.count += 1; } else { currentReferences.push({ srcType: rootObject.srcType, srcProjectId: rootObject.srcProjectId, srcDocumentId: rootObject.srcObjectId, count: 1 }); _.set(referenceMap, currentObjectPath, currentReferences); } } } else if (field.type === 'object' || field.type === 'model') { const fieldSets = 'locales' in field ? _.values(field.locales).map((fieldSet) => fieldSet.fields) : field.isUnset === true ? [] : [field.fields]; for (const fields of fieldSets) { iterateFields(fields, rootObject); } } else if (field.type === 'list') { const itemSets = 'locales' in field ? _.values(field.locales).map((fieldSet) => fieldSet.items) : [field.items]; for (const items of itemSets) { items.forEach((item) => iterateField(item, rootObject)); } } }; for (const document of documents) { iterateFields(document.fields, document); } return referenceMap; };