@augment-vir/common
Version:
A collection of augments, helpers types, functions, and classes for any JavaScript environment.
84 lines (83 loc) • 2.72 kB
JavaScript
import { check } from '@augment-vir/assert';
import { ensureError } from '@augment-vir/core';
import { filterMap } from '../array/filter.js';
import { getObjectTypedEntries, typedObjectFromEntries } from './object-entries.js';
/**
* Maps an object. The callback must return a key and value.
*
* @category Object
* @category Package : @augment-vir/common
* @example
*
* ```ts
* import {mapObject} from '@augment-vir/common';
*
* mapObject({a: 1, b: 2}, (key, value) => {
* return {
* key: `key-${key}`,
* value: `value-${value}`,
* };
* });
* // output is `{'key-a': 'value-1', 'key-b': 'value-2'}`
* ```
*
* @package [`@augment-vir/common`](https://www.npmjs.com/package/@augment-vir/common)
* @see
* - {@link mapObjectValues}: the variant that only maps values.
*/
export function mapObject(originalObject, mapCallback) {
try {
let gotAPromise = false;
const mappedEntries = getObjectTypedEntries(originalObject)
.map(([originalKey, originalValue,]) => {
const output = mapCallback(originalKey, originalValue, originalObject);
if (output instanceof Promise) {
gotAPromise = true;
return output;
}
else if (output) {
return [
output.key,
output.value,
];
}
else {
return undefined;
}
})
.filter(check.isTruthy);
if (gotAPromise) {
return new Promise(async (resolve, reject) => {
try {
const entries = filterMap(
/** This does contain promises. */
// eslint-disable-next-line @typescript-eslint/await-thenable
await Promise.all(mappedEntries), (entry) => {
if (!entry) {
return undefined;
}
else if (Array.isArray(entry)) {
return entry;
}
else {
return [
entry.key,
entry.value,
];
}
}, check.isTruthy);
resolve(typedObjectFromEntries(entries));
}
catch (error) {
reject(ensureError(error));
}
});
}
else {
return typedObjectFromEntries(mappedEntries);
}
}
catch (error) {
throw ensureError(error);
}
}