UNPKG

@parametricos/bcf-js

Version:

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

146 lines (120 loc) 3.96 kB
import JSZip from "jszip" import { IProject } from "./schema" import { IHelpers } from "./IHelpers" import { XMLBuilder } from "fast-xml-parser" export default class BcfWriter { version: string project?: IProject markups: any[] = [] files: any[] helpers: IHelpers constructor(version: string, helpers: IHelpers) { this.version = version this.helpers = helpers this.files = [] } addEntry = (file: IFile) => { if (file.path.endsWith('.version')) return this.files.push(file) } write = async (project: IProject): Promise<Buffer | undefined> => { try { this.project = project createEntries(this, project.markups) return await exportZip(this.files) } catch (e) { console.log("Error in writing BCF archive. The error below was thrown.") console.error(e) } } } function createEntries(writer: BcfWriter, markups: any) { if (!writer.project) return writer.addEntry(bcfversion(writer.version)) writer.addEntry(projectbcfp(writer.project.project_id, writer.project.name)) writer.addEntry(extensionssxd(writer)) for (const markup of markups) { const formattedMarkup = writer.helpers.MarkupToXmlNotation(markup) writer.markups.push(formattedMarkup) let xml = new XMLBuilder(writer.helpers.XmlBuilderOptions).build(formattedMarkup) xml = `<?xml version="1.0" encoding="utf-8"?>${xml}` if (markup.topic) { const guid = markup.topic.guid const newEntry = { path: `${guid}/markup.bcf`, content: xml } writer.addEntry(newEntry) } } } async function exportZip(files: IFile[]): Promise<Buffer> { var zip = new JSZip() for (const file of files) { const fullPath = file.path.split('/') if (!fullPath) continue if (fullPath.length == 1) zip.file(fullPath[0], file.content) else if (fullPath.length == 2) zip.folder(fullPath[0])?.file(fullPath[1], file.content) } return await zip.generateAsync({ type: "nodebuffer" }) } function bcfversion(version: string): IFile { return { path: 'bcf.version', content: `<?xml version="1.0" encoding="utf-8"?> <Version xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" VersionId="${version}"> <DetailedVersion>${version}</DetailedVersion> </Version>` } } function projectbcfp(projectId: string, projectName: string): IFile { return { path: 'project.bcfp', content: `<?xml version="1.0" encoding="utf-8"?> <ProjectExtension xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <Project ProjectId="${projectId}"> <Name>${projectName}</Name> </Project> <ExtensionSchema>extensions.xsd</ExtensionSchema> </ProjectExtension>` } } function extensionssxd(writer: BcfWriter): IFile { const attributes = [ 'version', 'encoding', 'standalone', 'xmlns', 'schemaLocation', 'name', 'base', 'value' ] const options = { additional_attributes: attributes, firstletter_uppercase: false, plural_to_singular: false } let helpers = writer.helpers if(writer.version == '3.0'){ const v21 = require('./2.1/index') const helpersV21: BcfWriter = new v21.BcfWriter() helpers = helpersV21.helpers } const formattedXml: any = helpers.RenameJsonKeys(writer.project?.extension_schema, options) let xml = new XMLBuilder(helpers.XmlBuilderOptions).build(formattedXml) return { path: 'extensions.xsd', content: xml } } interface IFile { path: string, content: string }