ravendb
Version:
RavenDB client for Node.js
315 lines • 11.1 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ObjectUtil = void 0;
const TypeUtil_js_1 = require("./TypeUtil.js");
const Constants_js_1 = require("../Constants.js");
function iden(x, locale) {
return x;
}
class ObjectUtil {
// WARNING: some methods are assigned below dynamically
static camelCase = (input, locale) => locale ? input[0].toLocaleUpperCase(locale) + input.slice(1) : input[0].toLowerCase() + input.slice(1);
static camel = ObjectUtil.camelCase;
static pascalCase = (input, locale) => locale ? input[0].toLocaleLowerCase(locale) + input.slice(1) : input[0].toUpperCase() + input.slice(1);
static pascal = ObjectUtil.pascalCase;
/**
* @deprecated Use deepJsonClone or deepLiteralClone for better performance
* @param o Object to clone
*/
static clone(o) {
// eslint-disable-next-line unicorn/prefer-structured-clone
return JSON.parse(JSON.stringify(o));
}
static deepJsonClone(o) {
// eslint-disable-next-line unicorn/prefer-structured-clone
return JSON.parse(JSON.stringify(o));
}
static deepLiteralClone(item) {
if (!item) {
return item;
}
let result;
if (Array.isArray(item)) {
result = [];
for (let index = 0; index < item.length; index++) {
result[index] = ObjectUtil.deepLiteralClone(item[index]);
}
}
else if (TypeUtil_js_1.TypeUtil.isObject(item)) {
result = {};
for (const prop in item) {
result[prop] = ObjectUtil.deepLiteralClone(item[prop]);
}
}
else {
result = item;
}
return result;
}
static mapToLiteral(input, valueTransformFunc) {
return Array.from(input.entries())
.reduce((obj, [key, value]) => (Object.assign(obj, {
[key]: valueTransformFunc
? valueTransformFunc(key, value)
: value
})), {});
}
static transformObjectKeys(obj, opts) {
const options = setDefaults(opts, DEFAULT_CHANGE_CASE_OPTIONS);
return transformObjectKeys(obj, options, []);
}
static transformDocumentKeys(obj, conventions) {
if (!obj) {
return obj;
}
const metadata = obj[Constants_js_1.CONSTANTS.Documents.Metadata.KEY];
const hasMetadata = Constants_js_1.CONSTANTS.Documents.Metadata.KEY in obj;
const transformedMetadata = hasMetadata ? ObjectUtil.transformMetadataKeys(metadata, conventions) : null;
if (!conventions.serverToLocalFieldNameConverter) {
// fast path - no need to transform entity - transform metadata only
if (hasMetadata) {
return {
...obj,
[Constants_js_1.CONSTANTS.Documents.Metadata.KEY]: transformedMetadata
};
}
else {
return obj;
}
}
const transformed = ObjectUtil.transformObjectKeys(obj, {
defaultTransform: conventions.serverToLocalFieldNameConverter
});
if (hasMetadata) {
transformed[Constants_js_1.CONSTANTS.Documents.Metadata.KEY] = transformedMetadata;
}
return transformed;
}
static transformMetadataKeys(metadata, conventions) {
if (!metadata) {
return metadata;
}
let result = {};
const userMetadataFieldsToTransform = {};
const needsCaseTransformation = !!conventions.serverToLocalFieldNameConverter;
for (const [key, value] of Object.entries(metadata)) {
if (key === Constants_js_1.CONSTANTS.Documents.Metadata.ATTACHMENTS) {
result[Constants_js_1.CONSTANTS.Documents.Metadata.ATTACHMENTS] = value ? value.map(x => ObjectUtil.mapAttachmentDetailsToLocalObject(x)) : null;
}
else if (key[0] === "@" || key === "Raven-Node-Type") {
result[key] = value;
}
else {
if (needsCaseTransformation) {
userMetadataFieldsToTransform[key] = value;
}
else {
result[key] = value;
}
}
}
if (Object.keys(userMetadataFieldsToTransform)) {
const transformedUserFields = ObjectUtil.transformObjectKeys(userMetadataFieldsToTransform, {
defaultTransform: conventions.serverToLocalFieldNameConverter
});
result = Object.assign(result, transformedUserFields);
}
return result;
}
static mapAttachmentDetailsToLocalObject(json) {
return {
changeVector: json.ChangeVector,
contentType: json.ContentType,
documentId: json.DocumentId,
hash: json.Hash,
name: json.Name,
size: json.Size
};
}
static mapIncludesToLocalObject(json, conventions) {
const mappedIncludes = {};
if (json) {
for (const [key, value] of Object.entries(json)) {
mappedIncludes[key] = ObjectUtil.transformDocumentKeys(value, conventions);
}
}
return mappedIncludes;
}
static mapCompareExchangeToLocalObject(json) {
if (!json) {
return undefined;
}
const result = {};
for (const [key, value] of Object.entries(json)) {
result[key] = {
index: value.Index,
key: value.Key,
changeVector: value.ChangeVector,
value: {
Object: value.Value?.Object
}
};
}
return result;
}
static mapTimeSeriesIncludesToLocalObject(json) {
if (!json) {
return undefined;
}
const result = {};
for (const [docId, perDocumentTimeSeries] of Object.entries(json)) {
const perDocumentResult = {};
for (const [tsName, tsData] of Object.entries(perDocumentTimeSeries)) {
perDocumentResult[tsName] = tsData.map(ts => {
return {
from: ts.From,
to: ts.To,
includes: ts.Includes,
totalResults: ts.TotalResults,
entries: ts.Entries.map(entry => ({
timestamp: entry.Timestamp,
isRollup: entry.IsRollup,
tag: entry.Tag,
values: entry.Values,
}))
};
});
}
result[docId] = perDocumentResult;
}
return result;
}
static mapCounterIncludesToLocalObject(json) {
const result = json ? {} : undefined;
if (json) {
for (const [key, value] of Object.entries(json)) {
result[key] = value.map(c => {
return c ? {
changeVector: c.ChangeVector,
counterName: c.CounterName,
counterValues: c.CounterValues,
documentId: c.DocumentId,
etag: c.Etag,
totalValue: c.TotalValue
} : null;
});
}
}
return result;
}
static isEmpty(object) {
return Object.keys(object ?? {}).length === 0;
}
}
exports.ObjectUtil = ObjectUtil;
const DEFAULT_CHANGE_CASE_OPTIONS = {
recursive: true,
arrayRecursive: true,
throwOnDuplicate: false,
locale: null,
ignoreKeys: [],
ignorePaths: [],
};
function setDefaults(object, defaults) {
object = object || {};
for (const i in defaults) {
// eslint-disable-next-line no-prototype-builtins
if (defaults.hasOwnProperty(i) && typeof object[i] === "undefined") {
object[i] = defaults[i];
}
}
return object;
}
function isObject(value) {
if (!value) {
return false;
}
return typeof value === "object" || typeof value === "function";
}
function isArray(value) {
return Array.isArray(value);
}
function computeNewValue(value, options, forceRecurse, stack) {
const valueIsArray = isArray(value);
if (valueIsArray && options.arrayRecursive) {
return transformArray(value, options, stack);
}
else if (isObject(value) && !valueIsArray && (options.recursive || forceRecurse)) {
return transformObjectKeys(value, options, stack);
}
else {
return value;
}
}
function transformArray(array, options, stack) {
if (!isArray(array)) {
throw new Error("transformArray expects an array");
}
const result = [];
stack = [...stack, "[]"];
for (const value of array) {
const newValue = computeNewValue(value, options, true, stack);
result.push(newValue);
}
stack.pop();
return result;
}
function makeKeyPath(keyStack) {
return keyStack.join(".");
}
function shouldTransformKey(currentKey, currentPath, opts) {
for (const x of opts.ignoreKeys) {
if ("test" in x ? x.test(currentKey) : x === currentKey) {
return false;
}
}
if (opts.ignorePaths) {
const currentPathPlusKey = currentPath ? currentPath + "." + currentKey : currentKey;
for (const x of opts.ignorePaths) {
if ("test" in x ? x.test(currentPathPlusKey) : x === currentPathPlusKey) {
return false;
}
}
}
return true;
}
function getTransformFunc(key, currentPath, opts) {
if (opts.paths) {
for (const p of opts.paths) {
if (!p.path) {
return p.transform;
}
else if (p.path.test(currentPath)) {
return p.transform ?? iden;
}
}
}
return opts.defaultTransform ?? iden;
}
function transformObjectKeys(object, options, stack) {
if (!object) {
return object;
}
const result = {};
for (const key in object) {
// eslint-disable-next-line no-prototype-builtins
if (object.hasOwnProperty(key)) {
const value = object[key];
let newKey = key;
const currentPath = makeKeyPath(stack);
if (shouldTransformKey(key, currentPath, options)) {
const f = getTransformFunc(key, currentPath, options);
newKey = f(key, options.locale ?? undefined);
}
// eslint-disable-next-line no-prototype-builtins
if (result.hasOwnProperty(newKey) && options.throwOnDuplicate) {
throw new Error("duplicated key " + newKey);
}
stack = [...stack, newKey];
result[newKey] = computeNewValue(value, options, false, stack);
stack.pop();
}
}
return result;
}
//# sourceMappingURL=ObjectUtil.js.map