forest-express-sequelize
Version:
Official Express/Sequelize Liana for Forest
108 lines (103 loc) • 4.43 kB
JavaScript
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;
;