UNPKG

@yellicode/elements

Version:

The meta model API for Yellicode - an extensible code generator.

92 lines (91 loc) 4.8 kB
/* * Copyright (c) 2020 Yellicode * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ import { ElementMapImpl } from '../element-map'; import { ModelDelegateImpl } from '../model-delegate'; import { Document as DocumentImpl } from '../document'; import { ElementVisitor } from './element-visitor'; import { ElementJSONTransformer } from './element-json-transformer'; import { DocumentJSONTransformer } from './document-json-transformer'; var ModelSerializer = /** @class */ (function () { function ModelSerializer() { } /** * A custom replacer function that is used as a replacer callback using JSON.stringify. * @param this The object in which the key was found. * @param key The key being stringified. * @param value The value being stringified. */ ModelSerializer.replacer = function (key, value) { // Initially, the replacer function is called with an empty string as key representing the object being stringified. // It is then called for each property on the object or array being stringified. if (!key.length) return value; // If the object is an array, keep all members if (Array.isArray(this)) return value; // If the value is falsy (false, 0, '', null), remove it from the output. if (!value) { return undefined; // by default, don't include the property } // If the value is an empty array, remove it var valueIsArray = Array.isArray(value); if (valueIsArray && !value.length) return undefined; // remove empty arrays // Should we apply a custom transformer? if (this.hasOwnProperty('modelTypeName')) { // This is a document (interfaces.Document). This only applies if serializeDocument was called. return DocumentJSONTransformer.toJSON(this, key, value); } // This is a element (interfaces.Element) or any other nested object, such as a TaggedValue return ElementJSONTransformer.toJSON(this, key, value, valueIsArray); }; ModelSerializer.serializeModel = function (model) { return JSON.stringify(model, ModelSerializer.replacer, 0); }; ModelSerializer.serializeDocument = function (document) { return JSON.stringify(document, ModelSerializer.replacer, 0); }; ModelSerializer.deserializeModel = function (text, applySorting, customTypeResolver) { var elementMap = new ElementMapImpl(customTypeResolver); var modelDelegate = new ModelDelegateImpl(elementMap); var visitor = new ElementVisitor(modelDelegate, applySorting); return ModelSerializer.deserializeModelInternal(text, visitor); }; ModelSerializer.deserializeModelInternal = function (text, visitor) { var modelData = JSON.parse(text); return visitor.visit(modelData); }; ModelSerializer.deserializeDocument = function (text, applySorting, customTypeResolver) { var elementMap = new ElementMapImpl(customTypeResolver); var modelDelegate = new ModelDelegateImpl(elementMap); var visitor = new ElementVisitor(modelDelegate, applySorting); // Because the order in which we deserialize the document parts is important, we need to // first split the data into references, profiles and the main model. // const documentData = JSON.parse(text, ModelSerializer.documentReviver) as SplitDocumentData; var documentData = JSON.parse(text); var props = { id: documentData.id, creator: documentData.creator, modelTypeName: documentData.modelTypeName, modelTypeVersion: documentData.modelTypeVersion }; var document = DocumentImpl.create(modelDelegate, props); // 1: resolve references if (documentData.references && documentData.references.length) { // Todo... console.warn('The document contains one or more references. Importing references is not supported yet.'); } // 2: Deserialize profiles. This is important to do before deserializing the model, because // the profiles (actually, their contained stereotypes) must be in the ElementMap. if (documentData.profiles) { document.profiles = visitor.visit(documentData.profiles); } // 3: deserialize the model (todo: apply profiles) if (documentData.model) { document.model = visitor.visit(documentData.model); } return document; }; return ModelSerializer; }()); export { ModelSerializer };