domain-objects
Version:
A simple, convenient way to represent domain objects, leverage domain knowledge, and add runtime validation in your code base.
67 lines • 3.51 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.omitMetadata = void 0;
const helpful_errors_1 = require("helpful-errors");
const type_fns_1 = require("type-fns");
const assertDomainObjectIsSafeToManipulate_1 = require("../constraints/assertDomainObjectIsSafeToManipulate");
const isOfDomainObject_1 = require("../instantiation/inherit/isOfDomainObject");
const getMetadataKeys_1 = require("./getMetadataKeys");
/**
* exposes a function which properly handles any value that can could have been defined for an object property
* - if domain object, omits metadata values
* - if array, recursively omits on each item in the array
* - if neither of the above, then its the terminal condition - return it, its fully omitted
*/
const recursivelyOmitMetadataFromObjectValue = (thisValue) => {
// handle directly nested domain object
if ((0, isOfDomainObject_1.isOfDomainObject)(thisValue))
return (0, exports.omitMetadata)(thisValue); // eslint-disable-line @typescript-eslint/no-use-before-define
// handle an array of one level deep (doesn't handle Array of Array, for simplicity)
if (Array.isArray(thisValue))
return thisValue.map(recursivelyOmitMetadataFromObjectValue); // run self on each item in the array, (i.e., recursively)
// handle any other value type
return thisValue;
};
/**
* omits all metadata values on a domain object
*
* relevance:
* - often in change detection, metadata values are not relevant, this provides an easy way to omit them
*
* features:
* - utilizes the `.metadata` property of the domain object definition to identify metadata keys
* - recall, the default is `id`, `uuid`, `createdAt`, `updatedAt`, `effectiveAt`
* - recursive, applies omission deeply
*
* note:
* - metadata is the most common readonly category, applicable to all domain objects
* - for broader readonly (including non-metadata externally-resolved attributes), use `omitReadonly`
*/
const omitMetadata = (obj) => {
// handle arrays
if (Array.isArray(obj))
return recursivelyOmitMetadataFromObjectValue(obj);
// make sure its an instance of DomainObject
if (!(0, isOfDomainObject_1.isOfDomainObject)(obj))
throw new helpful_errors_1.UnexpectedCodePathError('omitMetadata called on object that is not an instance of a DomainObject. Are you sure you instantiated the object? (Related: see `DomainObject.nested`)', { obj });
// get the metadata keys
const Constructor = obj.constructor; // https://stackoverflow.com/a/61444747/3068233
const metadataKeys = (0, getMetadataKeys_1.getMetadataKeys)(obj, {
nameOfFunctionNeededFor: 'omitMetadata',
});
// make sure that its safe to manipulate
(0, assertDomainObjectIsSafeToManipulate_1.assertDomainObjectIsSafeToManipulate)(obj);
// object with omit applied recursively on each property
const objectWithEachDomainObjectKeyRecursivelyOmitted = Object.entries(obj).reduce((summary, [thisKey, thisValue]) => {
return {
...summary,
[thisKey]: recursivelyOmitMetadataFromObjectValue(thisValue),
};
}, {});
// omit all of the metadata keys
const objWithoutBaseCaseAutogeneratedValues = (0, type_fns_1.omit)(objectWithEachDomainObjectKeyRecursivelyOmitted, metadataKeys);
// return the instantiated object
return new Constructor(objWithoutBaseCaseAutogeneratedValues);
};
exports.omitMetadata = omitMetadata;
//# sourceMappingURL=omitMetadata.js.map