UNPKG

forest-express-sequelize

Version:

Official Express/Sequelize Liana for Forest

108 lines (103 loc) 4.43 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); require("core-js/modules/es.promise.js"); require("core-js/modules/es.array.iterator.js"); function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } const _ = require('lodash'); const P = require('bluebird'); const Interface = require('forest-express'); const { ErrorHTTP422 } = require('./errors'); const ResourceGetter = require('./resource-getter'); const PrimaryKeysManager = require('./primary-keys-manager'); const associationRecord = require('../utils/association-record'); const isPrimaryKeyAForeignKey = require('../utils/is-primary-key-a-foreign-key'); class ResourceCreator { constructor(model, params, body, user) { this.model = model; this.params = params; this.body = body; this.schema = Interface.Schemas.schemas[model.name]; this.user = user; } async _getTargetKey(name, association) { const primaryKey = this.body[name]; let targetKey = primaryKey; if (primaryKey && association.targetKey !== association.target.primaryKeyAttribute) { const record = await associationRecord.get(association.target, primaryKey); targetKey = record[association.targetKey]; } return targetKey; } async _makePromisesBeforeSave(record, [name, association]) { if (association.associationType === 'BelongsTo') { const setterName = `set${_.upperFirst(name)}`; const targetKey = await this._getTargetKey(name, association); const primaryKeyIsAForeignKey = isPrimaryKeyAForeignKey(association); if (primaryKeyIsAForeignKey) { record[association.source.primaryKeyAttribute] = this.body[name]; } return record[setterName](targetKey, { save: false }); } return null; } _makePromisesAfterSave(record, [name, association]) { let setterName; if (association.associationType === 'HasOne') { setterName = `set${_.upperFirst(name)}`; } else if (['BelongsToMany', 'HasMany'].includes(association.associationType)) { setterName = `add${_.upperFirst(name)}`; } if (setterName) { return record[setterName](this.body[name]); } return null; } async _handleSave(record, callback) { var _this = this; const { associations } = this.model; if (associations) { await P.all(Object.entries(associations).map(function (entry) { return callback.bind(_this)(record, entry); })); } } async perform() { // buildInstance const recordCreated = this.model.build(this.body); // handleAssociationsBeforeSave await this._handleSave(recordCreated, this._makePromisesBeforeSave); const scopeFilters = await Interface.scopeManager.getScopeForUser(this.user, this.model.name, true); // saveInstance (validate then save) try { await recordCreated.validate(); } catch (error) { throw new ErrorHTTP422(error.message); } const record = await recordCreated.save(); // handleAssociationsAfterSave // NOTICE: Many to many associations have to be set after the record creation in order to // have an id. await this._handleSave(record, this._makePromisesAfterSave); // appendCompositePrimary new PrimaryKeysManager(this.model).annotateRecords([record]); try { return await new ResourceGetter(this.model, _objectSpread(_objectSpread({}, this.params), {}, { recordId: record[this.schema.idField] }), this.user).perform(); } catch (error) { if (error.statusCode === 404 && scopeFilters) { return record; } throw error; } } } module.exports = ResourceCreator;