forest-express
Version:
Official package for all Forest Express Lianas
202 lines (200 loc) • 8.6 kB
JavaScript
;
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;