@getanthill/datastore
Version:
Event-Sourced Datastore
146 lines • 5.4 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.unique = unique;
exports.random = random;
exports.getDate = getDate;
exports.getDateNow = getDateNow;
exports.mergeWithReplacedArrays = mergeWithReplacedArrays;
exports.mapValuesDeep = mapValuesDeep;
exports.deepCoerceProp = deepCoerceProp;
exports.deepCoerce = deepCoerce;
exports.processExplanationPlan = processExplanationPlan;
exports.validateEntity = validateEntity;
const node_assert_1 = __importDefault(require("node:assert"));
const node_crypto_1 = __importDefault(require("node:crypto"));
const node_util_1 = __importDefault(require("node:util"));
const lodash_1 = __importDefault(require("lodash"));
function unique(value, index, self) {
return self.indexOf(value) === index;
}
function random() {
return node_crypto_1.default.getRandomValues(new Uint8Array(1))[0] / 256;
}
function getDate(str) {
return !!str || str === 0 ? new Date(str) : new Date();
}
function getDateNow() {
return Date.now();
}
function mergeWithReplacedArrays(_srcValue, objValue) {
return Array.isArray(objValue) ? objValue : undefined;
}
function mapValuesDeep(obj, handler = (v) => v) {
Object.keys(obj).forEach((key) => {
obj[key] = handler(obj[key], key);
if (typeof obj[key] === 'object' && obj[key] !== null) {
obj[key] = mapValuesDeep(obj[key], handler);
}
});
return obj;
}
function deepCoerceProp(obj, schema, fn, path, name) {
const prop = obj[name];
const _path = [...path, name];
const _schema = lodash_1.default.get(schema.properties, name, schema);
const { type, format } = _schema;
if (type === 'array') {
obj[name] = deepCoerce(prop, _schema.items || {}, fn, _path);
return;
}
if (typeof prop === 'object' && prop !== null) {
obj[name] = deepCoerce(prop, _schema, fn, _path);
return;
}
if (type === 'integer') {
const _value = Number.parseInt(obj[name], 10);
if (isNaN(_value) === false) {
obj[name] = _value;
}
return;
}
if (type === 'number') {
const _value = parseFloat(obj[name]);
if (isNaN(_value) === false) {
obj[name] = _value;
}
return;
}
if (type === 'boolean') {
obj[name] = Boolean(JSON.parse(obj[name]));
return;
}
if ((format === 'date' || format === 'date-time') &&
(typeof obj[name] === 'string' || typeof obj[name] === 'number')) {
obj[name] = new Date(obj[name]);
return;
}
obj[name] = fn(prop, _schema, _path);
}
/**
* Deep coerce object against its JSON Schema
*
* @param {object} obj The object to freeze
* @returns {object} The freezed object
*/
function deepCoerce(obj, schema, fn = (v) => v, path = []) {
if (Object.isFrozen(obj)) {
return obj;
}
let propNames = Object.getOwnPropertyNames(obj);
if (Array.isArray(obj)) {
propNames = propNames.filter((p) => p !== 'length');
}
for (const name of propNames) {
deepCoerceProp(obj, schema, fn, path, name);
}
return obj;
}
function processExplanationPlan(raw) {
var _a, _b, _c;
const winningPlan = lodash_1.default.get(raw, 'queryPlanner.winningPlan');
const executionStats = lodash_1.default.get(raw, 'executionStats');
return {
stage: (_b = (_a = winningPlan === null || winningPlan === void 0 ? void 0 : winningPlan.inputStage) === null || _a === void 0 ? void 0 : _a.stage) !== null && _b !== void 0 ? _b : winningPlan === null || winningPlan === void 0 ? void 0 : winningPlan.stage,
executation_time_ms: executionStats === null || executionStats === void 0 ? void 0 : executionStats.executionTimeMillis,
index_name: (_c = winningPlan === null || winningPlan === void 0 ? void 0 : winningPlan.inputStage) === null || _c === void 0 ? void 0 : _c.indexName,
keys_examined: executionStats === null || executionStats === void 0 ? void 0 : executionStats.totalKeysExamined,
docs_examined: executionStats === null || executionStats === void 0 ? void 0 : executionStats.totalDocsExamined,
winning_plan: winningPlan,
raw,
};
}
function validateEntity(validator, entity, schema, throwOnInvalidEvent = true) {
const schemaId = `entity`;
let validate = validator.getSchema(schemaId);
if (!validate) {
validator.addSchema(schema, schemaId);
validate = validator.getSchema(schemaId);
}
const isValid = validate(entity);
if (isValid === false && throwOnInvalidEvent === true) {
const assertionErrorPayload = {
message: 'State schema validation error',
expected: null,
actual: node_util_1.default.inspect({
schema,
entity,
errors: validate.errors,
}, false, null, false),
};
const err = new node_assert_1.default.AssertionError(assertionErrorPayload);
// @ts-ignore
err.details = validate.errors;
// @ts-ignore
err.details.push({
entity,
});
// @ts-ignore
err.entity = entity;
throw err;
}
return isValid;
}
//# sourceMappingURL=index.js.map