Files
personal_site/frontend/node_modules/@aws-cdk/toolkit-lib/lib/util/objects.js
T

237 lines
24 KiB
JavaScript
Raw Normal View History

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.applyDefaults = applyDefaults;
exports.isEmpty = isEmpty;
exports.deepClone = deepClone;
exports.mapObject = mapObject;
exports.makeObject = makeObject;
exports.deepGet = deepGet;
exports.deepSet = deepSet;
exports.deepMerge = deepMerge;
exports.splitBySize = splitBySize;
exports.transformObjectKeys = transformObjectKeys;
exports.noUndefined = noUndefined;
const types_1 = require("./types");
const toolkit_error_1 = require("../toolkit/toolkit-error");
/**
* Return a new object by adding missing keys into another object
*/
function applyDefaults(hash, defaults) {
const result = {};
Object.keys(hash).forEach(k => result[k] = hash[k]);
Object.keys(defaults)
.filter(k => !(k in result))
.forEach(k => result[k] = defaults[k]);
return result;
}
/**
* Return whether the given parameter is an empty object or empty list.
*/
function isEmpty(x) {
if (x == null) {
return false;
}
if ((0, types_1.isArray)(x)) {
return x.length === 0;
}
return Object.keys(x).length === 0;
}
/**
* Deep clone a tree of objects, lists or scalars
*
* Does not support cycles.
*/
function deepClone(x) {
if (typeof x === 'undefined') {
return undefined;
}
if (x === null) {
return null;
}
if ((0, types_1.isArray)(x)) {
return x.map(deepClone);
}
if ((0, types_1.isObject)(x)) {
return makeObject(mapObject(x, (k, v) => [k, deepClone(v)]));
}
return x;
}
/**
* Map over an object, treating it as a dictionary
*/
function mapObject(x, fn) {
const ret = [];
Object.keys(x).forEach(key => {
ret.push(fn(key, x[key]));
});
return ret;
}
/**
* Construct an object from a list of (k, v) pairs
*/
function makeObject(pairs) {
const ret = {};
for (const pair of pairs) {
ret[pair[0]] = pair[1];
}
return ret;
}
/**
* Deep get a value from a tree of nested objects
*
* Returns undefined if any part of the path was unset or
* not an object.
*/
function deepGet(x, path) {
path = path.slice();
while (path.length > 0 && (0, types_1.isObject)(x)) {
const key = path.shift();
x = x[key];
}
return path.length === 0 ? x : undefined;
}
/**
* Deep set a value in a tree of nested objects
*
* Throws an error if any part of the path is not an object.
*/
function deepSet(x, path, value) {
path = path.slice();
if (path.length === 0) {
throw new toolkit_error_1.ToolkitError('Path may not be empty');
}
while (path.length > 1 && (0, types_1.isObject)(x)) {
const key = path.shift();
if (isPrototypePollutingKey(key)) {
continue;
}
if (!(key in x)) {
x[key] = {};
}
x = x[key];
}
if (!(0, types_1.isObject)(x)) {
throw new toolkit_error_1.ToolkitError(`Expected an object, got '${x}'`);
}
const finalKey = path[0];
if (isPrototypePollutingKey(finalKey)) {
return;
}
if (value !== undefined) {
x[finalKey] = value;
}
else {
delete x[finalKey];
}
}
/**
* Helper to detect prototype polluting keys
*
* A key matching this, MUST NOT be used in an assignment.
* Use this to check user-input.
*/
function isPrototypePollutingKey(key) {
return key === '__proto__' || key === 'constructor' || key === 'prototype';
}
/**
* Recursively merge objects together
*
* The leftmost object is mutated and returned. Arrays are not merged
* but overwritten just like scalars.
*
* If an object is merged into a non-object, the non-object is lost.
*/
function deepMerge(...objects) {
function mergeOne(target, source) {
for (const key of Object.keys(source)) {
if (isPrototypePollutingKey(key)) {
continue;
}
const value = source[key];
if ((0, types_1.isObject)(value)) {
if (!(0, types_1.isObject)(target[key])) {
target[key] = {};
} // Overwrite on purpose
mergeOne(target[key], value);
}
else if (typeof value !== 'undefined') {
target[key] = value;
}
}
}
const others = objects.filter(x => x != null);
if (others.length === 0) {
return {};
}
const into = others.splice(0, 1)[0];
others.forEach(other => mergeOne(into, other));
return into;
}
/**
* Splits the given object into two, such that:
*
* 1. The size of the first object (after stringified in UTF-8) is less than or equal to the provided size limit.
* 2. Merging the two objects results in the original one.
*/
function splitBySize(data, maxSizeBytes) {
if (maxSizeBytes < 2) {
// It's impossible to fit anything in the first object
return [undefined, data];
}
const entries = Object.entries(data);
return recurse(0, 0);
function recurse(index, runningTotalSize) {
if (index >= entries.length) {
// Everything fits in the first object
return [data, undefined];
}
const size = runningTotalSize + entrySize(entries[index]);
return (size > maxSizeBytes) ? cutAt(index) : recurse(index + 1, size);
}
function entrySize(entry) {
return Buffer.byteLength(JSON.stringify(Object.fromEntries([entry])));
}
function cutAt(index) {
return [
Object.fromEntries(entries.slice(0, index)),
Object.fromEntries(entries.slice(index)),
];
}
}
/**
* This function transforms all keys (recursively) in the provided `val` object.
*
* @param val - The object whose keys need to be transformed.
* @param transform - The function that will be applied to each key.
* @param exclude - The keys that will not be transformed and copied to output directly
* @returns A new object with the same values as `val`, but with all keys transformed according to `transform`.
*/
function transformObjectKeys(val, transform, exclude = {}) {
if (val == null || typeof val !== 'object') {
return val;
}
if (Array.isArray(val)) {
// For arrays we just pass parent's exclude object directly
// since it makes no sense to specify different exclude options for each array element
return val.map((input) => transformObjectKeys(input, transform, exclude));
}
const ret = {};
for (const [k, v] of Object.entries(val)) {
const childExclude = exclude[k];
if (childExclude === true) {
// we don't transform this object if the key is specified in exclude
ret[transform(k)] = v;
}
else {
ret[transform(k)] = transformObjectKeys(v, transform, childExclude);
}
}
return ret;
}
/**
* Remove undefined values from a dictionary
*/
function noUndefined(xs) {
return Object.fromEntries(Object.entries(xs).filter(([_, v]) => v !== undefined));
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib2JqZWN0cy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIm9iamVjdHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFPQSxzQ0FVQztBQUtELDBCQVFDO0FBT0QsOEJBY0M7QUFLRCw4QkFNQztBQUtELGdDQU1DO0FBUUQsMEJBUUM7QUFPRCwwQkFtQ0M7QUFvQkQsOEJBNkJDO0FBUUQsa0NBNEJDO0FBWUQsa0RBb0JDO0FBS0Qsa0NBRUM7QUE5UEQsbUNBQTRDO0FBQzVDLDREQUF3RDtBQUV4RDs7R0FFRztBQUNILFNBQWdCLGFBQWEsQ0FBQyxJQUFTLEVBQUUsUUFBYTtJQUNwRCxNQUFNLE1BQU0sR0FBUSxFQUFHLENBQUM7SUFFeEIsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFFcEQsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUM7U0FDbEIsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxNQUFNLENBQUMsQ0FBQztTQUMzQixPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFFekMsT0FBTyxNQUFNLENBQUM7QUFDaEIsQ0FBQztBQUVEOztHQUVHO0FBQ0gsU0FBZ0IsT0FBTyxDQUFDLENBQU07SUFDNUIsSUFBSSxDQUFDLElBQUksSUFBSSxFQUFFLENBQUM7UUFDZCxPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7SUFDRCxJQUFJLElBQUEsZUFBTyxFQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7UUFDZixPQUFPLENBQUMsQ0FBQyxNQUFNLEtBQUssQ0FBQyxDQUFDO0lBQ3hCLENBQUM7SUFDRCxPQUFPLE1BQU0s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