UNPKG

forest-express

Version:

Official package for all Forest Express Lianas

202 lines (200 loc) 8.6 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _ = require('lodash'); var P = require('bluebird'); var moment = require('moment'); var semver = require('semver'); var JSONAPISerializer = require('jsonapi-serializer').Serializer; var SmartFieldsValuesInjector = require('../services/smart-fields-values-injector'); var Schemas = require('../generators/schemas'); var logger = require('../services/logger'); function ResourceSerializer(Implementation, model, records, integrator, meta, fieldsSearched, searchValue, fieldsPerModel) { var modelName = Implementation.getModelName(model); var schema = Schemas.schemas[modelName]; var needsDateOnlyFormating = Implementation.getLianaName() === 'forest-express-sequelize' && semver.lt(Implementation.getOrmVersion(), '4.0.0'); var reservedWords = ['meta', 'attributes']; var fieldInfoDateonly = []; var fieldInfoPoint = []; function getFieldsNames(fields) { return fields.map(function (field) { if (reservedWords.indexOf(field.field) > -1) { return "".concat(field.field, ":namespace").concat(field.field); } return field.field; }); } function detectFieldWithSpecialFormat(field, fieldReference) { if (field.type === 'Dateonly' && needsDateOnlyFormating) { fieldInfoDateonly.push({ name: field.field, association: fieldReference }); } if (field.type === 'Point') { fieldInfoPoint.push({ name: field.field, association: fieldReference }); } } this.perform = function () { var typeForAttributes = {}; function getAttributesFor(dest, fields) { _.map(fields, function (field) { detectFieldWithSpecialFormat(field); if (field.integration) { if (integrator) { integrator.defineSerializationOption(model, schema, dest, field); } } else { var fieldName = field.field; if (reservedWords.indexOf(fieldName) > -1) { fieldName = "namespace".concat(fieldName); } if (_.isPlainObject(field.type)) { dest[fieldName] = { attributes: getFieldsNames(field.type.fields) }; getAttributesFor(dest[field.field], field.type.fields); } else if (field.reference) { var referenceType = field.reference.split('.')[0]; var referenceSchema = Schemas.schemas[referenceType]; typeForAttributes[field.field] = referenceType; if (!referenceSchema) { logger.error("Cannot find the '".concat(referenceType, "' reference field for '").concat(schema.name, "' collection.")); return; } var fieldReference = referenceSchema.idField; if (_.isArray(field.type) && !fieldReference && referenceSchema.isVirtual) { if (_.find(referenceSchema.fields, function (schemaField) { return schemaField.field === 'id'; })) { fieldReference = 'id'; } else { logger.warn("Cannot find the 'idField' attribute in your '".concat(referenceSchema.name, "' Smart Collection declaration.")); } } _.each(referenceSchema.fields, function (schemaField) { detectFieldWithSpecialFormat(schemaField, fieldName); }); dest[fieldName] = { ref: fieldReference, attributes: getFieldsNames(referenceSchema.fields), relationshipLinks: { related: function related(dataSet) { return { href: "/forest/".concat(Implementation.getModelName(model), "/").concat(dataSet[schema.idField], "/relationships/").concat(field.field) }; } } }; if (_.isArray(field.type)) { dest[fieldName].ignoreRelationshipData = true; dest[fieldName].included = false; } } } }); } function formatFields(record) { var offsetServer = moment().utcOffset() / 60; _.each(fieldInfoDateonly, function (fieldInfo) { var dateonly; if (fieldInfo.association && record[fieldInfo.association] && fieldInfo.name && record[fieldInfo.association][fieldInfo.name]) { dateonly = moment.utc(record[fieldInfo.association][fieldInfo.name]).add(offsetServer, 'h'); record[fieldInfo.association][fieldInfo.name] = dateonly.format(); } if (fieldInfo.name && record[fieldInfo.name]) { dateonly = moment.utc(record[fieldInfo.name]).add(offsetServer, 'h'); record[fieldInfo.name] = dateonly.format(); } }); _.each(fieldInfoPoint, function (fieldInfo) { if (fieldInfo.association && record[fieldInfo.association] && fieldInfo.name && record[fieldInfo.association][fieldInfo.name]) { record[fieldInfo.association][fieldInfo.name] = record[fieldInfo.association][fieldInfo.name].coordinates; } if (!fieldInfo.association && fieldInfo.name && record[fieldInfo.name]) { record[fieldInfo.name] = record[fieldInfo.name].coordinates; } }); } var attributes = getFieldsNames(schema.fields); var serializationOptions = { id: schema.idField, attributes: attributes, keyForAttribute: function keyForAttribute(key) { return key; }, typeForAttribute: function typeForAttribute(attribute) { return typeForAttributes[attribute] || attribute; }, meta: meta }; if (Implementation !== null && Implementation !== void 0 && Implementation.Flattener) { var flattenedFieldsNames = attributes === null || attributes === void 0 ? void 0 : attributes.filter(function (attribute) { return Implementation.Flattener._isFieldFlattened(attribute); }); var flattenedFieldsAccessors = flattenedFieldsNames === null || flattenedFieldsNames === void 0 ? void 0 : flattenedFieldsNames.map(function (elem) { return (0, _defineProperty2["default"])({}, elem, Implementation.Flattener.splitOnSeparator(elem)); }); if (flattenedFieldsAccessors.length) { serializationOptions.transform = function (record) { flattenedFieldsAccessors.forEach(function (accessors) { Object.entries(accessors).forEach(function (_ref2) { var _ref3 = (0, _slicedToArray2["default"])(_ref2, 2), fieldName = _ref3[0], accessor = _ref3[1]; var value = accessor.reduce(function (a, prop) { return a ? a[prop] : undefined; }, record); if (value !== undefined) { record[fieldName] = value; } }); }); return record; }; } } getAttributesFor(serializationOptions, schema.fields); // NOTICE: Format Dateonly field types before serialization. if (_.isArray(records)) { _.each(records, function (record) { formatFields(record); }); } else { formatFields(records); } return new P(function (resolve) { if (_.isArray(records)) { var smartFieldsValuesInjector; resolve(P.map(records, function (record) { smartFieldsValuesInjector = new SmartFieldsValuesInjector(record, modelName, fieldsPerModel); return smartFieldsValuesInjector.perform(); }).then(function (result) { if (fieldsSearched && smartFieldsValuesInjector) { fieldsSearched = fieldsSearched.concat(smartFieldsValuesInjector.getFieldsForHighlightedSearch()); } return result; })); } else { resolve(new SmartFieldsValuesInjector(records, modelName, fieldsPerModel).perform()); } }).then(function () { var decorators = null; if (searchValue) { decorators = Implementation.RecordsDecorator.decorateForSearch(records, fieldsSearched, searchValue); if (decorators) { serializationOptions.meta = { decorators: decorators }; } } }).then(function () { return new JSONAPISerializer(schema.name, records, serializationOptions); }); }; } module.exports = ResourceSerializer;