UNPKG

forest-express

Version:

Official package for all Forest Express Lianas

208 lines (206 loc) 10.2 kB
"use strict"; 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); }); }; };