UNPKG

@parametricos/bcf-js

Version:

BCF.js is a BIM Collaboration Format (BCF) reader & parser.

201 lines (161 loc) 6.51 kB
import { IComment, IFile, IMarkup, IViewPoint } from "../schema" import { XMLParser } from "fast-xml-parser" import * as SharedHelpers from '../SharedHelpers' export namespace Helpers { export const XmlParserOptions = SharedHelpers.XmlParserOptions export const XmlBuilderOptions = SharedHelpers.XmlBuilderOptions export const GetViewpoint = SharedHelpers.GetViewpoint export const XmlToJsonNotation = SharedHelpers.XmlToJsonNotation const ChangeToUppercase = SharedHelpers.ChangeToUppercase export function GetMarkup(xmlString: any): IMarkup { const { Markup } = new XMLParser(XmlParserOptions).parse(xmlString) return { header: { files: getHeaderFiles(Markup.Header) }, topic: { guid: Markup.Topic['@_Guid'], topic_type: Markup.Topic["@_TopicType"], topic_status: Markup.Topic["@_TopicStatus"], reference_links: Markup.Topic["ReferenceLink"] && Helpers.ObjectToArray(Markup.Topic["ReferenceLink"]), title: Markup.Topic["Title"], priority: Markup.Topic["Priority"], index: Markup.Topic["Index"], labels: Markup.Topic["Labels"] && Helpers.ObjectToArray(Markup.Topic["Labels"]), creation_date: Markup.Topic["CreationDate"], creation_author: Markup.Topic["CreationAuthor"], modified_date: Markup.Topic["ModifiedDate"], modified_author: Markup.Topic["ModifiedAuthor"], assigned_to: Markup.Topic["AssignedTo"], description: Markup.Topic["Description"], // bim_snippets: Markup.ITopic["BimSnippet"] ? , // related_topics: Markup.ITopic["ReferenceLink"], comments: Helpers.GetComments(Markup.Comment), viewpoints: Helpers.GetViewpoints(Markup.Viewpoints) }, } } export function GetViewpoints(data: any) { if (!data) return const constructViewpoint = (data: any): IViewPoint => { return { guid: data["@_Guid"], viewpoint: data["Viewpoint"], snapshot: data["Snapshot"] } } const viewpoints: IViewPoint[] = [] if (Array.isArray(data)) { data.forEach((x) => { viewpoints.push(constructViewpoint(x)) }) } else { viewpoints.push(constructViewpoint(data)) } return viewpoints } export function GetComments(data: any) { if (!data) return const constructComment = (data: any): IComment => { return { guid: data["@_Guid"], date: data["Date"], author: data["Author"], comment: data["Comment"], viewpoint: data?.Viewpoint?.["@_Guid"], modified_date: data["ModifiedDate"], modified_author: data["ModifiedAuthor"] } } const viewpoints: IComment[] = [] if (Array.isArray(data)) { data.forEach((x) => { viewpoints.push(constructComment(x)) }) } else { viewpoints.push(constructComment(data)) } return viewpoints } /** * Returns an object as an array * Can also accept array and returns new array if type is unknown * * @return data as an array * @param data */ export function ObjectToArray(data: any) { return Array.isArray(data) ? data : [data] } export function ParsePoint(point: any) { return { x: point.X, y: point.Y, z: point.Z } } const version21PluralWordsToSingular = [ "DocumentReferences", "RelatedTopics" ] export function MarkupToXmlNotation(markup: any): any { const convertedMarkup = convert21To30(markup) let purgedMarkup = { "Markup": { "@_xmlns:xsi": "http://www.w3.org/2001/XMLSchema-instance", "@_xmlns:xsd": "http://www.w3.org/2001/XMLSchema", "header": convertedMarkup.header, "topic": convertedMarkup.topic, "comment": convertedMarkup.comment, "viewpoints": convertedMarkup.viewpoints } } return RenameJsonKeys(purgedMarkup) } export function RenameJsonKeys(obj: any, options?: any) { let outputObj: any = {} if (typeof obj === 'string') return obj const opt_plural_to_singular = options?.plural_to_singular !== undefined ? options.plural_to_singular : true for (const key in obj) { let value = obj[key] if (!value) continue if (key.startsWith('@_')) { outputObj[key] = value continue } let newKey = ChangeToUppercase(key, options) if (Array.isArray(value)) { const newArrNode: any[] = [] for (const child of value) newArrNode.push(RenameJsonKeys(child, options)) const pluralWord = version21PluralWordsToSingular.find(word => word.startsWith(newKey)) if (pluralWord && opt_plural_to_singular) newKey = pluralWord.slice(0, -1) outputObj[newKey] = newArrNode continue } if (typeof value === 'object') value = RenameJsonKeys(value, options) outputObj[newKey] = value } return outputObj } function getHeaderFiles(header: any): IFile[] | undefined { if (header) return Helpers.ObjectToArray(header).map((file: any) => XmlToJsonNotation(file)) } function convert21To30(markup: IMarkup): any { if (!markup.topic) return const { comments, viewpoints, ...topic } = markup.topic const newMarkup = { header: { file: markup.header?.files }, topic: topic, comment: comments, viewpoints: viewpoints } return newMarkup } }