forest-express
Version:
Official package for all Forest Express Lianas
208 lines (206 loc) • 10.2 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 _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
var _require = require('@forestadmin/context'),
inject = _require.inject;
var _ = require('lodash');
var nodePath = require('path');
var SchemaUtil = require('../utils/schema');
var auth = require('../services/auth');
var path = require('../services/path');
var ResourceSerializer = require('../serializers/resource');
var Schemas = require('../generators/schemas');
var CSVExporter = require('../services/csv-exporter');
var ResourceDeserializer = require('../deserializers/resource');
var ParamsFieldsDeserializer = require('../deserializers/params-fields');
var RecordsGetter = require('../services/exposed/records-getter');
module.exports = function Associations(app, model, Implementation, integrator, opts) {
var _inject = inject(),
modelsManager = _inject.modelsManager;
var modelName = Implementation.getModelName(model);
var schema = Schemas.schemas[modelName];
function getAssociationField(associationName) {
var field = _.find(schema.fields, {
field: associationName
});
if (field && field.reference) {
return field.reference.split('.')[0];
}
return null;
}
function getAssociation(request) {
var pathSplit = request.route.path.split('/');
var associationName = pathSplit[pathSplit.length - 1];
if (nodePath.extname(associationName) === '.csv') {
associationName = nodePath.basename(associationName, '.csv');
} else if (associationName === 'count') {
associationName = pathSplit[pathSplit.length - 2];
}
return {
associationName: associationName
};
}
function getContext(request) {
var association = getAssociation(request);
var params = _.extend(request.query, request.params, association);
var models = modelsManager.getModels();
var associationField = getAssociationField(params.associationName);
var associationModel = _.find(models, function (refModel) {
return Implementation.getModelName(refModel) === associationField;
});
return {
params: params,
associationModel: associationModel
};
}
function list(request, response, next) {
var _getContext = getContext(request),
params = _getContext.params,
associationModel = _getContext.associationModel;
var fieldsPerModel = new ParamsFieldsDeserializer(params.fields).perform();
return new Implementation.HasManyGetter(model, associationModel, opts, params, request.user).perform().then(function (_ref) {
var _ref2 = (0, _slicedToArray2["default"])(_ref, 2),
records = _ref2[0],
fieldsSearched = _ref2[1];
return new ResourceSerializer(Implementation, associationModel, records, integrator, null, fieldsSearched, params.search, fieldsPerModel).perform();
}).then(function (records) {
return response.send(records);
})["catch"](next);
}
function count(request, response, next) {
var _getContext2 = getContext(request),
params = _getContext2.params,
associationModel = _getContext2.associationModel;
return new Implementation.HasManyGetter(model, associationModel, opts, params, request.user).count().then(function (recordsCount) {
return response.send({
count: recordsCount
});
})["catch"](next);
}
function exportCSV(_x, _x2, _x3) {
return _exportCSV.apply(this, arguments);
}
function _exportCSV() {
_exportCSV = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee(request, response, next) {
var _getContext3, params, associationModel, recordsExporter;
return _regenerator["default"].wrap(function _callee$(_context) {
while (1) switch (_context.prev = _context.next) {
case 0:
_getContext3 = getContext(request), params = _getContext3.params, associationModel = _getContext3.associationModel;
recordsExporter = new Implementation.ResourcesExporter(model, opts, params, associationModel, request.user);
return _context.abrupt("return", new CSVExporter(params, response, Implementation.getModelName(associationModel), recordsExporter).perform()["catch"](next));
case 3:
case "end":
return _context.stop();
}
}, _callee);
}));
return _exportCSV.apply(this, arguments);
}
function add(request, response, next) {
var params = _.extend(request.params, getAssociation(request));
var data = request.body;
var models = modelsManager.getModels();
var associationField = getAssociationField(params.associationName);
var associationModel = _.find(models, function (innerModel) {
return Implementation.getModelName(innerModel) === associationField;
});
return new Implementation.HasManyAssociator(model, associationModel, opts, params, data).perform().then(function () {
response.status(204).send();
})["catch"](next);
}
function remove(_x4, _x5, _x6) {
return _remove.apply(this, arguments);
}
function _remove() {
_remove = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee2(request, response, next) {
var _getContext4, params, associationModel, body, hasBodyAttributes, isLegacyRequest, getter, ids;
return _regenerator["default"].wrap(function _callee2$(_context2) {
while (1) switch (_context2.prev = _context2.next) {
case 0:
_getContext4 = getContext(request), params = _getContext4.params, associationModel = _getContext4.associationModel;
// NOTICE: There are three ways to receive request data from frontend:
// - Legacy: `{ body: { data: [ { id: 1, … }, { id: 2, … }, … ]} }`.
// - IDs (select some)
// - Or query params (select all).
//
// The HasManyDissociator currently accepts a `data` parameter that has to be formatted
// as the legacy one.
hasBodyAttributes = request.body && request.body.data && request.body.data.attributes;
isLegacyRequest = request.body && request.body.data && Array.isArray(request.body.data);
if (!(!hasBodyAttributes && isLegacyRequest)) {
_context2.next = 7;
break;
}
body = request.body;
_context2.next = 13;
break;
case 7:
if (!hasBodyAttributes) {
_context2.next = 13;
break;
}
getter = new RecordsGetter(associationModel, request.user, request.query);
_context2.next = 11;
return getter.getIdsFromRequest(request);
case 11:
ids = _context2.sent;
body = {
data: ids.map(function (id) {
return {
id: id
};
})
};
case 13:
return _context2.abrupt("return", new Implementation.HasManyDissociator(model, associationModel, opts, params, body).perform().then(function () {
response.status(204).send();
})["catch"](next));
case 14:
case "end":
return _context2.stop();
}
}, _callee2);
}));
return _remove.apply(this, arguments);
}
function update(request, response, next) {
var params = _.extend(request.params, getAssociation(request));
var data = request.body;
var models = modelsManager.getModels();
var associationField = getAssociationField(params.associationName);
var associationModel = _.find(models, function (innerModel) {
return Implementation.getModelName(innerModel) === associationField;
});
return new Implementation.BelongsToUpdater(model, associationModel, opts, params, data).perform().then(function () {
response.status(204).send();
})["catch"](next);
}
function updateEmbeddedDocument(association) {
return function (request, response, next) {
return new ResourceDeserializer(Implementation, model, request.body, false).perform().then(function (record) {
return new Implementation.EmbeddedDocumentUpdater(model, request.params, association, record).perform();
}).then(function () {
return response.status(204).send();
})["catch"](next);
};
}
this.perform = function () {
// NOTICE: HasMany associations routes
_.each(SchemaUtil.getHasManyAssociations(schema), function (association) {
app.get(path.generate("".concat(modelName, "/:recordId/relationships/").concat(association.field, ".csv"), opts), auth.ensureAuthenticated, exportCSV);
app.get(path.generate("".concat(modelName, "/:recordId/relationships/").concat(association.field), opts), auth.ensureAuthenticated, list);
app.get(path.generate("".concat(modelName, "/:recordId/relationships/").concat(association.field, "/count"), opts), auth.ensureAuthenticated, count);
app.post(path.generate("".concat(modelName, "/:recordId/relationships/").concat(association.field), opts), auth.ensureAuthenticated, add);
// NOTICE: This route only works for embedded has many
app.put(path.generate("".concat(modelName, "/:recordId/relationships/").concat(association.field, "/:recordIndex"), opts), auth.ensureAuthenticated, updateEmbeddedDocument(association.field));
app["delete"](path.generate("".concat(modelName, "/:recordId/relationships/").concat(association.field), opts), auth.ensureAuthenticated, remove);
});
// NOTICE: belongsTo associations routes
_.each(SchemaUtil.getBelongsToAssociations(schema), function (association) {
app.put(path.generate("".concat(modelName, "/:recordId/relationships/").concat(association.field), opts), auth.ensureAuthenticated, update);
});
};
};