"use strict";
require("core-js/modules/es.object.keys.js");
require("core-js/modules/es.symbol.js");
require("core-js/modules/es.array.filter.js");
require("core-js/modules/es.object.get-own-property-descriptor.js");
require("core-js/modules/web.dom-collections.for-each.js");
require("core-js/modules/es.object.get-own-property-descriptors.js");
require("core-js/modules/es.array.iterator.js");
require("core-js/modules/es.string.iterator.js");
require("core-js/modules/es.weak-map.js");
require("core-js/modules/web.dom-collections.iterator.js");
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
var _typeof = require("@babel/runtime/helpers/typeof");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.addInitialRelationship = addInitialRelationship;
exports.createEntitiesHandler = createEntitiesHandler;
exports.entityEditorMarkup = entityEditorMarkup;
exports.entityMergeMarkup = entityMergeMarkup;
exports.generateEntityMergeProps = generateEntityMergeProps;
exports.generateEntityProps = generateEntityProps;
exports.generateUnifiedProps = generateUnifiedProps;
exports.makeEntityCreateOrEditHandler = makeEntityCreateOrEditHandler;
exports.unifiedFormMarkup = unifiedFormMarkup;
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
require("core-js/modules/es.array.concat.js");
require("core-js/modules/es.object.assign.js");
require("core-js/modules/es.function.name.js");
require("core-js/modules/es.array.find.js");
require("core-js/modules/es.object.to-string.js");
require("core-js/modules/es.array.includes.js");
var _get2 = _interopRequireDefault(require("lodash/get"));
var _camelCase2 = _interopRequireDefault(require("lodash/camelCase"));
var _pick2 = _interopRequireDefault(require("lodash/pick"));
var _size2 = _interopRequireDefault(require("lodash/size"));
var _startCase2 = _interopRequireDefault(require("lodash/startCase"));
var _kebabCase2 = _interopRequireDefault(require("lodash/kebabCase"));
var _partialRight2 = _interopRequireDefault(require("lodash/partialRight"));
var _upperFirst2 = _interopRequireDefault(require("lodash/upperFirst"));
var Immutable = _interopRequireWildcard(require("immutable"));
var React = _interopRequireWildcard(require("react"));
var UnifiedFormHelpers = _interopRequireWildcard(require("../../client/unified-form/helpers"));
var entityEditorHelpers = _interopRequireWildcard(require("../../client/entity-editor/helpers"));
var entityRoutes = _interopRequireWildcard(require("../routes/entity/entity"));
var error = _interopRequireWildcard(require("../../common/helpers/error"));
var propHelpers = _interopRequireWildcard(require("../../client/helpers/props"));
var unifiedRoutes = _interopRequireWildcard(require("../routes/entity/process-unified-form"));
var utils = _interopRequireWildcard(require("./utils"));
var _utils2 = require("../../common/helpers/utils");
var _entityEditor = _interopRequireDefault(require("../../client/entity-editor/entity-editor"));
var _entityMerge = _interopRequireDefault(require("../../client/entity-editor/entity-merge"));
var _layout = _interopRequireDefault(require("../../client/containers/layout"));
var _reactRedux = require("react-redux");
var _server = _interopRequireDefault(require("react-dom/server"));
var _unifiedForm = _interopRequireDefault(require("../../client/unified-form/unified-form"));
var _redux = require("redux");
var _props2 = require("./props");
var _excluded = ["initialState"],
_excluded2 = ["initialState"],
_excluded3 = ["initialState"];
/*
* Copyright (C) 2017 Eshan Singh
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
var ufCreateRootReducer = UnifiedFormHelpers.createRootReducer;
var createRootReducer = entityEditorHelpers.createRootReducer,
getEntitySection = entityEditorHelpers.getEntitySection,
getEntitySectionMerge = entityEditorHelpers.getEntitySectionMerge,
getValidator = entityEditorHelpers.getValidator;
var validEntityTypes = ['author', 'edition', 'editionGroup', 'publisher', 'series', 'work'];
/**
* Callback to get the initial state
* @callback initialStateCallback
* @param {object} entity - entity
*/
/**
* Returns a props object with reasonable defaults for entity creation/editing.
* @param {string} entityType - entity type
* @param {request} req - request object
* @param {response} res - response object
* @param {object} additionalProps - additional props
* @param {initialStateCallback} initialStateCallback - callback
* to get the initial state
* @returns {object} - props
*/
function generateEntityProps(entityType, req, res, additionalProps) {
var initialStateCallback = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : function () {
return new Object();
};
var entityName = (0, _upperFirst2.default)(entityType);
var entity = res.locals.entity;
var isEdit = Boolean(entity);
var getFilteredIdentifierTypes = isEdit ? (0, _partialRight2.default)(utils.filterIdentifierTypesByEntity, entity) : (0, _partialRight2.default)(_utils2.filterIdentifierTypesByEntityType, entityName);
var filteredIdentifierTypes = getFilteredIdentifierTypes(res.locals.identifierTypes);
var entityNameForRoute = (0, _kebabCase2.default)(entityType);
var submissionUrl = isEdit ? "/".concat(entityNameForRoute, "/").concat(entity.bbid, "/edit/handler") : "/".concat(entityNameForRoute, "/create/handler");
var action = isEdit ? 'edit' : 'create';
var props = Object.assign({
action: action,
entityType: entityType,
heading: isEdit ? "Edit ".concat(entity.defaultAlias ? entity.defaultAlias.name : '(unnamed)', " (").concat(entityName, ")") : "Add ".concat(entityName),
identifierTypes: filteredIdentifierTypes,
initialState: initialStateCallback(entity),
isMerge: false,
languageOptions: res.locals.languages,
requiresJS: true,
subheading: isEdit ? "Edit an existing ".concat(entityName, " on BookBrainz") : "Add a new ".concat(entityName, " to BookBrainz"),
submissionUrl: submissionUrl
}, additionalProps);
return (0, _props2.generateProps)(req, res, props);
}
/**
* Callback to get the initial state
* @callback initialStateCallback
* @param {object} entity - entity
*/
/**
* Returns a props object with reasonable defaults for entity creation/editing.
* @param {request} req - request object
* @param {response} res - response object
* @param {object} additionalProps - additional props
* @param {initialStateCallback} initialStateCallback - callback
* to get the initial state
* @returns {object} - props
*/
function generateEntityMergeProps(req, res, additionalProps) {
var initialStateCallback = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : function () {
return new Object();
};
var entityType = additionalProps.entityType,
mergingEntities = additionalProps.mergingEntities;
var entityName = (0, _startCase2.default)(entityType);
var entity = mergingEntities[0];
var getFilteredIdentifierTypes = (0, _partialRight2.default)(utils.filterIdentifierTypesByEntity, entity);
var filteredIdentifierTypes = getFilteredIdentifierTypes(res.locals.identifierTypes);
var submissionUrl = "/".concat((0, _kebabCase2.default)(entityType), "/").concat(entity.bbid, "/merge/handler");
var props = Object.assign({
entityType: entityType,
heading: "Merge ".concat(mergingEntities.length, " ").concat(entityName, "s"),
identifierTypes: filteredIdentifierTypes,
initialState: initialStateCallback(mergingEntities),
isMerge: true,
languageOptions: res.locals.languages,
requiresJS: true,
subheading: "You are merging ".concat(mergingEntities.length, " existing ").concat(entityName, "s:"),
submissionUrl: submissionUrl
}, additionalProps);
return (0, _props2.generateProps)(req, res, props);
}
/**
* Return markup for the entity editor.
* This also modifies the props value with a new initialState!
* @param {object} props - react props
* @returns {object} - Updated props and HTML string with markup
*/
function entityEditorMarkup(props) {
var initialState = props.initialState,
rest = (0, _objectWithoutProperties2.default)(props, _excluded);
var rootReducer = createRootReducer(props.entityType);
var store = (0, _redux.createStore)(rootReducer, Immutable.fromJS(initialState));
var EntitySection = getEntitySection(props.entityType);
var markup = _server.default.renderToString( /*#__PURE__*/React.createElement(_layout.default, propHelpers.extractLayoutProps(rest), /*#__PURE__*/React.createElement(_reactRedux.Provider, {
store: store
}, /*#__PURE__*/React.createElement(_entityEditor.default, (0, _extends2.default)({
validate: getValidator(props.entityType)
}, propHelpers.extractChildProps(rest)), /*#__PURE__*/React.createElement(EntitySection, null)))));
return {
markup: markup,
props: Object.assign({}, props, {
intitialState: store.getState()
})
};
}
/**
* Return markup for the entity merging tool.
* This also modifies the props value with a new initialState!
* @param {object} props - react props
* @returns {object} - Updated props and HTML string with markup
*/
function entityMergeMarkup(props) {
var initialState = props.initialState,
rest = (0, _objectWithoutProperties2.default)(props, _excluded2);
var rootReducer = createRootReducer(props.entityType, true);
var store = (0, _redux.createStore)(rootReducer, Immutable.fromJS(initialState));
var EntitySection = getEntitySectionMerge(props.entityType);
var markup = _server.default.renderToString( /*#__PURE__*/React.createElement(_layout.default, propHelpers.extractLayoutProps(rest), /*#__PURE__*/React.createElement(_reactRedux.Provider, {
store: store
}, /*#__PURE__*/React.createElement(_entityMerge.default, (0, _extends2.default)({
validate: getValidator(props.entityType)
}, propHelpers.extractChildProps(rest)), /*#__PURE__*/React.createElement(EntitySection, null)))));
return {
markup: markup,
props: Object.assign({}, props, {
intitialState: store.getState()
})
};
}
/**
* Callback for any transformations to the request body
* @callback transformCallback
* @param {object} body - request body
*/
/**
* Handler for create or edit actions
* @callback transformCallback
* @param {object} req - request object
* @param {object} res - response object
*/
/**
* Makes a middleware handler for create or edit actions on entities.
* @param {string} entityType - entity type
* @param {transformCallback} transformNewForm - callback for transformations
* @param {(string|string[])} propertiesToPick - props from transformed
* request body to pick.
* @param {boolean} isMergeHandler - Wether the submission was from a /merge/handler route
* @returns {createOrEditHandler} createOrEditHandler - middleware handler
*/
function makeEntityCreateOrEditHandler(entityType, transformNewForm, propertiesToPick) {
var isMergeHandler = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
var entityName = (0, _upperFirst2.default)(entityType);
var validate = getValidator(entityType);
return function createOrEditHandler(req, res) {
var mergeQueue = req.session.mergeQueue;
var isMergeOperation = isMergeHandler && mergeQueue && (0, _size2.default)(mergeQueue.mergingEntities) >= 2;
if (!validate(req.body, null, isMergeOperation)) {
var err = new error.FormSubmissionError();
error.sendErrorAsJSON(res, err);
}
req.body = transformNewForm(req.body);
return entityRoutes.handleCreateOrEditEntity(req, res, entityName, (0, _pick2.default)(req.body, propertiesToPick), isMergeOperation);
};
}
/**
* add an initial relationship to entity from another enitty
* when one entity created from other.
* @param {object} props - props related to new entity
* @param {number} relationshipTypeId - relationshipId number for initaial relationship
* @param {object} targetEntity - details about target entitiy like edition group, publisher and author
* @param {number} relationshipIndex - initial relationship index number
*/
function addInitialRelationship(props, relationshipTypeId, relationshipIndex, targetEntity) {
// Prepend 'i' here to indicate initail relationship row identifier
var rowId = "i".concat(relationshipIndex || 0);
var relationship = props.relationshipTypes.find(function (relationshipType) {
return relationshipType.id === relationshipTypeId;
});
var targetEntityDetail = {
bbid: targetEntity.id,
defaultAlias: {
name: targetEntity.text
},
type: targetEntity.type
};
var sourceEntityDetail = {
defaultAlias: {
name: ''
},
type: (0, _upperFirst2.default)(props.entityType)
};
var initialRelationship = {
attributes: [],
isAdded: true,
label: relationship.linkPhrase,
relationshipType: relationship,
rowID: rowId,
sourceEntity: targetEntity.type === 'EditionGroup' || targetEntity.type === 'Work' ? sourceEntityDetail : targetEntityDetail,
targetEntity: targetEntity.type === 'EditionGroup' || targetEntity.type === 'Work' ? targetEntityDetail : sourceEntityDetail
};
if (!props.initialState.relationshipSection) {
props.initialState.relationshipSection = {};
props.initialState.relationshipSection.canEdit = true;
props.initialState.relationshipSection.lastRelationships = null;
props.initialState.relationshipSection.relationshipEditorProps = null;
props.initialState.relationshipSection.relationshipEditorVisible = false;
}
props.initialState.relationshipSection.relationships = _objectSpread(_objectSpread({}, props.initialState.relationshipSection.relationships), {}, (0, _defineProperty2.default)({}, rowId, initialRelationship));
return props;
}
/**
* Return markup for the unified form.
* This also modifies the props value with a new initialState!
* @param {object} props - react props
* @returns {object} - Updated props and HTML string with markup
*/
function unifiedFormMarkup(props) {
var initialState = props.initialState,
rest = (0, _objectWithoutProperties2.default)(props, _excluded3);
var rootReducer = ufCreateRootReducer();
var store = (0, _redux.createStore)(rootReducer, Immutable.fromJS(initialState));
var markup = _server.default.renderToString( /*#__PURE__*/React.createElement(_layout.default, propHelpers.extractLayoutProps(rest), /*#__PURE__*/React.createElement(_reactRedux.Provider, {
store: store
}, /*#__PURE__*/React.createElement(_unifiedForm.default, props))));
return {
markup: markup,
props: Object.assign({}, props, {
initialState: store.getState()
})
};
}
/**
* Returns a props object with reasonable defaults for unified form.
* @param {request} req - request object
* @param {response} res - response object
* @param {object} additionalProps - additional props
* @param {initialStateCallback} initialStateCallback - callback
* to get the initial state
* @returns {object} - props
*/
function generateUnifiedProps(req, res, additionalProps) {
var initialStateCallback = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : function () {
return new Object();
};
var submissionUrl = '/create/handler';
var props = Object.assign({
allIdentifierTypes: res.locals.identifierTypes,
entityType: 'edition',
initialState: initialStateCallback(),
isUnifiedForm: true,
languageOptions: res.locals.languages,
requiresJS: true,
submissionUrl: submissionUrl
}, additionalProps);
return (0, _props2.generateProps)(req, res, props);
}
/**
* Validate Unified form
* @param {object} body - request body
* @returns {boolean}
*/
function validateUnifiedForm(body) {
for (var entityKey in body) {
if (Object.prototype.hasOwnProperty.call(body, entityKey)) {
var entityForm = body[entityKey];
var entityType = (0, _camelCase2.default)(entityForm.type);
var isNew = (0, _get2.default)(entityForm, '__isNew__', true);
var bbid = (0, _get2.default)(entityForm, 'id', null);
// for existing entity, it must have id attribute set to its bbid
if (!isNew && (!bbid || !(0, _utils2.isValidBBID)(bbid))) {
return false;
}
if (!entityType || !validEntityTypes.includes(entityType)) {
return false;
}
var validator = getValidator(entityType);
if (isNew && !validator(entityForm)) {
return false;
}
}
}
return true;
}
/**
* Middleware for handling unified form submission
* @param {object} req - Request object
* @param {object} res - Response object
*/
function createEntitiesHandler(_x, _x2) {
return _createEntitiesHandler.apply(this, arguments);
}
function _createEntitiesHandler() {
_createEntitiesHandler = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(req, res) {
var orm, err;
return _regenerator.default.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
orm = req.app.locals.orm; // generate the state for current entity
_context.next = 3;
return unifiedRoutes.preprocessForm(req.body, orm);
case 3:
req.body = _context.sent;
if (validateUnifiedForm(req.body)) {
_context.next = 7;
break;
}
err = new error.FormSubmissionError();
return _context.abrupt("return", error.sendErrorAsJSON(res, err));
case 7:
// transforming uf state into separate entity state
req.body = unifiedRoutes.transformForm(req.body);
return _context.abrupt("return", unifiedRoutes.handleCreateMultipleEntities(req, res));
case 9:
case "end":
return _context.stop();
}
}
}, _callee);
}));
return _createEntitiesHandler.apply(this, arguments);
}
//# sourceMappingURL=entityRouteUtils.js.map