forest-express
Version:
Official package for all Forest Express Lianas
129 lines (124 loc) • 5.85 kB
JavaScript
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
var _ = require('lodash');
var logger = require('./logger');
var Schemas = require('../generators/schemas');
var DEPTH_MAX_FOR_INJECTION = 0;
function SmartFieldsValuesInjector(record, modelName, fieldsPerModel) {
var depth = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0;
var requestedField = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : null;
var schema = Schemas.schemas[modelName];
var fieldsForHighlightedSearch = [];
this.getFieldsForHighlightedSearch = function () {
return fieldsForHighlightedSearch;
};
// NOTICE: Field reference format: `modelName.property`.
function getReferencedModelName(field) {
return field.reference.split('.')[0];
}
// eslint-disable-next-line
function setSmartFieldValue(record, field, modelName) {
if (field.value) {
logger.warn("DEPRECATION WARNING: Smart Fields \"value\" method is deprecated. Please use \"get\" method in your collection ".concat(modelName, " instead."));
}
var value;
try {
value = field.get ? field.get(record) : field.value(record);
} catch (error) {
logger.error("Cannot retrieve the ".concat(field.field, " value because of an internal error in the getter implementation: "), error);
}
if (!_.isNil(value)) {
if (!_.isFunction(value.then)) {
value = Promise.resolve(value);
}
return value.then( /*#__PURE__*/function () {
var _ref = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee(smartFieldValue) {
var smartFieldsValuesInjector;
return _regenerator["default"].wrap(function _callee$(_context) {
while (1) switch (_context.prev = _context.next) {
case 0:
if (!(depth <= DEPTH_MAX_FOR_INJECTION && smartFieldValue && field.reference)) {
_context.next = 4;
break;
}
smartFieldsValuesInjector = new SmartFieldsValuesInjector(smartFieldValue, getReferencedModelName(field), fieldsPerModel, depth + 1, field.field);
_context.next = 4;
return smartFieldsValuesInjector.perform();
case 4:
// NOTICE: Sequelize magic accessors can be overriden here
// but it is not an issue as they are not used in the process of adding
// smart fields
record[field.field] = smartFieldValue;
// NOTICE: String fields can be highlighted.
if (field.type === 'String') {
fieldsForHighlightedSearch.push(field.field);
}
case 6:
case "end":
return _context.stop();
}
}, _callee);
}));
return function (_x) {
return _ref.apply(this, arguments);
};
}())["catch"](function (error) {
logger.warn("Cannot set the ".concat(field.field, " value because of an unexpected error: "), error);
});
}
}
function isRequestedField(modelNameToCheck, fieldName) {
return fieldsPerModel && fieldsPerModel[modelNameToCheck] && fieldsPerModel[modelNameToCheck].indexOf(fieldName) !== -1;
}
// eslint-disable-next-line sonarjs/cognitive-complexity
function injectSmartFieldValue(field) {
var fieldWasRequested = isRequestedField(requestedField || modelName, field.field);
if (record && field.isVirtual && (field.get || field.value)) {
if (fieldsPerModel && !fieldWasRequested) {
return null;
}
return setSmartFieldValue(record, field, modelName);
}
if (!record[field.field] && _.isArray(field.type) && (field.relationship || field.isVirtual)) {
// Add empty arrays on relation fields so that JsonApiSerializer add the relevant
// `data.x.relationships` section in the response.
//
// The field must match the following condition
// - field is a real or a smart HasMany / BelongsToMany relation
// - field is NOT an 'embedded' relationship (@see mongoose)
record[field.field] = [];
} else if (field.reference && !_.isArray(field.type)) {
// NOTICE: Set Smart Fields values to "belongsTo" associated records.
var modelNameAssociation = getReferencedModelName(field);
var schemaAssociation = Schemas.schemas[modelNameAssociation];
if (schemaAssociation && !_.isArray(field.type)) {
return Promise.all(schemaAssociation.fields.map(function (fieldAssociation) {
if (record && record[field.field] && fieldAssociation.isVirtual && (fieldAssociation.get || fieldAssociation.value)) {
if (fieldsPerModel && !isRequestedField(field.field, fieldAssociation.field)) {
return null;
}
return setSmartFieldValue(record[field.field], fieldAssociation, modelNameAssociation);
}
return null;
}));
}
}
return null;
}
this.perform = /*#__PURE__*/(0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee2() {
return _regenerator["default"].wrap(function _callee2$(_context2) {
while (1) switch (_context2.prev = _context2.next) {
case 0:
return _context2.abrupt("return", Promise.all(schema.fields.map(function (field) {
return injectSmartFieldValue(field);
})));
case 1:
case "end":
return _context2.stop();
}
}, _callee2);
}));
}
module.exports = SmartFieldsValuesInjector;