mvom
Version:
Multivalue Object Mapper
113 lines (105 loc) • 3.75 kB
JavaScript
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _lodash = require("lodash");
var _Document = _interopRequireDefault(require("../Document"));
var _utils = require("../utils");
var _BaseSchemaType = _interopRequireDefault(require("./BaseSchemaType"));
/** A Document Array Schema Type */
class DocumentArrayType extends _BaseSchemaType.default {
/** An instance of Schema representing the document structure of the array's contents */
constructor(valueSchema) {
super();
this.valueSchema = valueSchema;
}
/**
* Cast to array of documents
* @throws {@link TypeError} Throws if a non-null/non-object is passed
*/
cast(value) {
if (value == null) {
return [];
}
return (0, _utils.ensureArray)(value).map(subdocument => {
// convert subdocument to a plain structure and then recast as document
const plainValue = subdocument == null ? {} : JSON.parse(JSON.stringify(subdocument));
if (!(0, _lodash.isPlainObject)(plainValue)) {
throw new TypeError('Cast value must be an object');
}
return _Document.default.createSubdocumentFromData(this.valueSchema, plainValue);
});
}
/** Get value from mv data */
get(record) {
return [...this.makeSubDocument(record)];
}
/** Set specified document array value into mv record */
set(originalRecord, documents) {
const record = (0, _lodash.cloneDeep)(originalRecord);
const mvPaths = this.valueSchema.getMvPaths();
// A subdocumentArray is always overwritten entirely so clear out all associated fields
mvPaths.forEach(path => {
(0, _lodash.set)(record, path, null);
});
documents.forEach((subdocument, iteration) => {
const subrecord = subdocument.transformDocumentToRecord();
mvPaths.forEach(path => {
const value = (0, _lodash.get)(subrecord, path, null);
(0, _lodash.set)(record, path.concat(iteration), value);
});
});
return record;
}
/** Validate the document array */
validate(documentList) {
return documentList.reduce((acc, document, index) => {
const documentErrors = document.validate();
documentErrors.forEach((messages, keyPath) => {
if (messages.length > 0) {
const errorsMapKey = `${index}.${keyPath}`;
acc.set(errorsMapKey, messages);
}
});
return acc;
}, new Map());
}
/** Create an array of foreign key definitions that will be validated before save */
transformForeignKeyDefinitionsToDb(documentList) {
return documentList.map(document => {
const documentForeignKeyDefinitions = document.buildForeignKeyDefinitions();
return documentForeignKeyDefinitions.map(({
filename,
entityName,
entityIds
}) => entityIds.map(entityId => ({
filename,
entityName,
entityId
})));
}).flat(2);
}
/** Generate subdocument instances */
*makeSubDocument(record) {
const makeSubRecord = iteration => this.valueSchema.getMvPaths().reduce((acc, path) => {
const value = this.getFromMvArray(path.concat([iteration]), record);
if (typeof value !== 'undefined') {
(0, _lodash.set)(acc, path, value);
}
return acc;
}, []);
let iteration = 0;
while (true) {
const subRecord = makeSubRecord(iteration);
if (subRecord.length === 0) {
return;
}
const subdocument = _Document.default.createSubdocumentFromRecord(this.valueSchema, subRecord);
yield subdocument;
iteration += 1;
}
}
}
var _default = exports.default = DocumentArrayType;