aws-cdk
Version:
CDK Toolkit, the command line tool for CDK apps
183 lines • 18 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.splitBySize = exports.deepMerge = exports.deepSet = exports.deepGet = exports.makeObject = exports.mapObject = exports.deepClone = exports.isEmpty = exports.applyDefaults = void 0;
const types_1 = require("./types");
/**
* 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;
}
exports.applyDefaults = applyDefaults;
/**
* 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;
}
exports.isEmpty = isEmpty;
/**
* 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;
}
exports.deepClone = deepClone;
/**
* 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;
}
exports.mapObject = mapObject;
/**
* 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;
}
exports.makeObject = makeObject;
/**
* 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;
}
exports.deepGet = deepGet;
/**
* 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 Error('Path may not be empty');
}
while (path.length > 1 && (0, types_1.isObject)(x)) {
const key = path.shift();
if (!(key in x)) {
x[key] = {};
}
x = x[key];
}
if (!(0, types_1.isObject)(x)) {
throw new Error(`Expected an object, got '${x}'`);
}
if (value !== undefined) {
x[path[0]] = value;
}
else {
delete x[path[0]];
}
}
exports.deepSet = deepSet;
/**
* 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 (key === '__proto__' || key === 'constructor') {
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;
}
exports.deepMerge = deepMerge;
/**
* 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)),
];
}
}
exports.splitBySize = splitBySize;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib2JqZWN0cy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIm9iamVjdHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsbUNBQWlEO0FBRWpEOztHQUVHO0FBQ0gsU0FBZ0IsYUFBYSxDQUFDLElBQVMsRUFBRSxRQUFhO0lBQ3BELE1BQU0sTUFBTSxHQUFRLEVBQUcsQ0FBQztJQUV4QixNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUVwRCxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQztTQUNsQixNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLE1BQU0sQ0FBQyxDQUFDO1NBQzNCLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUV6QyxPQUFPLE1BQU0sQ0FBQztBQUNoQixDQUFDO0FBVkQsc0NBVUM7QUFFRDs7R0FFRztBQUNILFNBQWdCLE9BQU8sQ0FBQyxDQUFNO0lBQzVCLElBQUksQ0FBQyxJQUFJLElBQUksRUFBRTtRQUFFLE9BQU8sS0FBSyxDQUFDO0tBQUU7SUFDaEMsSUFBSSxJQUFBLGVBQU8sRUFBQyxDQUFDLENBQUMsRUFBRTtRQUFFLE9BQU8sQ0FBQyxDQUFDLE1BQU0sS0FBSyxDQUFDLENBQUM7S0FBRTtJQUMxQyxPQUFPLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxLQUFLLENBQUMsQ0FBQztBQUNyQyxDQUFDO0FBSkQsMEJBSUM7QUFFRDs7OztHQUlHO0FBQ0gsU0FBZ0IsU0FBUyxDQUFDLENBQU07SUFDOUIsSUFBSSxPQUFPLENBQUMsS0FBSyxXQUFXLEVBQUU7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UyxDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUN4RSxDQUFDO0lBRUQsU0FBUyxLQUFLLENBQUMsS0FBYTtRQUMxQixPQUFPO1lBQ0wsTUFBTSxDQUFDLFdBQVcsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUMzQyxNQUFNLENBQUMsV0FBVyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUM7U0FDekMsQ0FBQztJQUNKLENBQUM7QUFDSCxDQUFDO0FBNUJELGtDQTRCQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGlzQXJyYXksIGlzT2JqZWN0LCBPYmogfSBmcm9tICcuL3R5cGVzJztcblxuLyoqXG4gKiBSZXR1cm4gYSBuZXcgb2JqZWN0IGJ5IGFkZGluZyBtaXNzaW5nIGtleXMgaW50byBhbm90aGVyIG9iamVjdFxuICovXG5leHBvcnQgZnVuY3Rpb24gYXBwbHlEZWZhdWx0cyhoYXNoOiBhbnksIGRlZmF1bHRzOiBhbnkpIHtcbiAgY29uc3QgcmVzdWx0OiBhbnkgPSB7IH07XG5cbiAgT2JqZWN0LmtleXMoaGFzaCkuZm9yRWFjaChrID0+IHJlc3VsdFtrXSA9IGhhc2hba10pO1xuXG4gIE9iamVjdC5rZXlzKGRlZmF1bHRzKVxuICAgIC5maWx0ZXIoayA9PiAhKGsgaW4gcmVzdWx0KSlcbiAgICAuZm9yRWFjaChrID0+IHJlc3VsdFtrXSA9IGRlZmF1bHRzW2tdKTtcblxuICByZXR1cm4gcmVzdWx0O1xufVxuXG4vKipcbiAqIFJldHVybiB3aGV0aGVyIHRoZSBnaXZlbiBwYXJhbWV0ZXIgaXMgYW4gZW1wdHkgb2JqZWN0IG9yIGVtcHR5IGxpc3QuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0VtcHR5KHg6IGFueSkge1xuICBpZiAoeCA9PSBudWxsKSB7IHJldHVybiBmYWxzZTsgfVxuICBpZiAoaXNBcnJheSh4KSkgeyByZXR1cm4geC5sZW5ndGggPT09IDA7IH1cbiAgcmV0dXJuIE9iamVjdC5rZXlzKHgpLmxlbmd0aCA9PT0gMDtcbn1cblxuLyoqXG4gKiBEZWVwIGNsb25lIGEgdHJlZSBvZiBvYmplY3RzLCBsaXN0cyBvciBzY2FsYXJzXG4gKlxuICogRG9lcyBub3Qgc3VwcG9ydCBjeWNsZXMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkZWVwQ2xvbmUoeDogYW55KTogYW55IHtcbiAgaWYgKHR5cGVvZiB4ID09PSAndW5kZWZpbmVkJykgeyByZXR1cm4gdW5kZWZpbmVkOyB9XG4gIGlmICh4ID09PSBudWxsKSB7IHJldHVybiBudWxsOyB9XG4gIGlmIChpc0FycmF5KHgpKSB7IHJldHVybiB4Lm1hcChkZWVwQ2xvbmUpOyB9XG4gIGlmIChpc09iamVjdCh4KSkgeyByZXR1cm4gbWFrZU9iamVjdChtYXBPYmplY3QoeCwgKGssIHYpID0+IFtrLCBkZWVwQ2xvbmUodildIGFzIFtzdHJpbmcsIGFueV0pKTsgfVxuICByZXR1cm4geDtcbn1cblxuLyoqXG4gKiBNYXAgb3ZlciBhbiBvYmplY3QsIHRyZWF0aW5nIGl0IGFzIGEgZGljdGlvbmFyeVxuICovXG5leHBvcnQgZnVuY3Rpb24gbWFwT2JqZWN0PFQsIFU+KHg6IE9iajxUPiwgZm46IChrZXk6IHN0cmluZywgdmFsdWU6IFQpID0+IFUpOiBVW10ge1xuICBjb25zdCByZXQ6IFVbXSA9IFtdO1xuICBPYmplY3Qua2V5cyh4KS5mb3JFYWNoKGtleSA9PiB7XG4gICAgcmV0LnB1c2goZm4oa2V5LCB4W2tleV0pKTtcbiAgfSk7XG4gIHJldHVybiByZXQ7XG59XG5cbi8qKlxuICogQ29uc3RydWN0IGFuIG9iamVjdCBmcm9tIGEgbGlzdCBvZiAoaywgdikgcGFpcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1ha2VPYmplY3Q8VD4ocGFpcnM6IEFycmF5PFtzdHJpbmcsIFRdPik6IE9iajxUPiB7XG4gIGNvbnN0IHJldDogT2JqPFQ+ID0ge307XG4gIGZvciAoY29uc3QgcGFpciBvZiBwYWlycykge1xuICAgIHJldFtwYWlyWzBdXSA9IHBhaXJbMV07XG4gIH1cbiAgcmV0dXJuIHJldDtcbn1cblxuLyoqXG4gKiBEZWVwIGdldCBhIHZhbHVlIGZyb20gYSB0cmVlIG9mIG5lc3RlZCBvYmplY3RzXG4gKlxuICogUmV0dXJucyB1bmRlZmluZWQgaWYgYW55IHBhcnQgb2YgdGhlIHBhdGggd2FzIHVuc2V0IG9yXG4gKiBub3QgYW4gb2JqZWN0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gZGVlcEdldCh4OiBhbnksIHBhdGg6IHN0cmluZ1tdKTogYW55IHtcbiAgcGF0aCA9IHBhdGguc2xpY2UoKTtcblxuICB3aGlsZSAocGF0aC5sZW5ndGggPiAwICYmIGlzT2JqZWN0KHgpKSB7XG4gICAgY29uc3Qga2V5ID0gcGF0aC5zaGlmdCgpITtcbiAgICB4ID0geFtrZXldO1xuICB9XG4gIHJldHVybiBwYXRoLmxlbmd0aCA9PT0gMCA/IHggOiB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogRGVlcCBzZXQgYSB2YWx1ZSBpbiBhIHRyZWUgb2YgbmVzdGVkIG9iamVjdHNcbiAqXG4gKiBUaHJvd3MgYW4gZXJyb3IgaWYgYW55IHBhcnQgb2YgdGhlIHBhdGggaXMgbm90IGFuIG9iamVjdC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRlZXBTZXQoeDogYW55LCBwYXRoOiBzdHJpbmdbXSwgdmFsdWU6IGFueSkge1xuICBwYXRoID0gcGF0aC5zbGljZSgpO1xuXG4gIGlmIChwYXRoLmxlbmd0aCA9PT0gMCkge1xuICAgIHRocm93IG5ldyBFcnJvcignUGF0aCBtYXkgbm90IGJlIGVtcHR5Jyk7XG4gIH1cblxuICB3aGlsZSAocGF0aC5sZW5ndGggPiAxICYmIGlzT2JqZWN0KHgpKSB7XG4gICAgY29uc3Qga2V5ID0gcGF0aC5zaGlmdCgpITtcbiAgICBpZiAoIShrZXkgaW4geCkpIHsgeFtrZXldID0ge307IH1cbiAgICB4ID0geFtrZXldO1xuICB9XG5cbiAgaWYgKCFpc09iamVjdCh4KSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgRXhwZWN0ZWQgYW4gb2JqZWN0LCBnb3QgJyR7eH0nYCk7XG4gIH1cblxuICBpZiAodmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgIHhbcGF0aFswXV0gPSB2YWx1ZTtcbiAgfSBlbHNlIHtcbiAgICBkZWxldGUgeFtwYXRoWzBdXTtcbiAgfVxufVxuXG4vKipcbiAqIFJlY3Vyc2l2ZWx5IG1lcmdlIG9iamVjdHMgdG9nZXRoZXJcbiAqXG4gKiBUaGUgbGVmdG1vc3Qgb2JqZWN0IGlzIG11dGF0ZWQgYW5kIHJldHVybmVkLiBBcnJheXMgYXJlIG5vdCBtZXJnZWRcbiAqIGJ1dCBvdmVyd3JpdHRlbiBqdXN0IGxpa2Ugc2NhbGFycy5cbiAqXG4gKiBJZiBhbiBvYmplY3QgaXMgbWVyZ2VkIGludG8gYSBub24tb2JqZWN0LCB0aGUgbm9uLW9iamVjdCBpcyBsb3N0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gZGVlcE1lcmdlKC4uLm9iamVjdHM6IEFycmF5PE9iajxhbnk+IHwgdW5kZWZpbmVkPikge1xuICBmdW5jdGlvbiBtZXJnZU9uZSh0YXJnZXQ6IE9iajxhbnk+LCBzb3VyY2U6IE9iajxhbnk+KSB7XG4gICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXMoc291cmNlKSkge1xuICAgICAgaWYgKGtleSA9PT0gJ19fcHJvdG9fXycgfHwga2V5ID09PSAnY29uc3RydWN0b3InKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBjb25zdCB2YWx1ZSA9IHNvdXJjZVtrZXldO1xuXG4gICAgICBpZiAoaXNPYmplY3QodmFsdWUpKSB7XG4gICAgICAgIGlmICghaXNPYmplY3QodGFyZ2V0W2tleV0pKSB7IHRhcmdldFtrZXldID0ge307IH0gLy8gT3ZlcndyaXRlIG9uIHB1cnBvc2VcbiAgICAgICAgbWVyZ2VPbmUodGFyZ2V0W2tleV0sIHZhbHVlKTtcbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHZhbHVlICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICB0YXJnZXRba2V5XSA9IHZhbHVlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGNvbnN0IG90aGVycyA9IG9iamVjdHMuZmlsdGVyKHggPT4geCAhPSBudWxsKSBhcyBBcnJheTxPYmo8YW55Pj47XG5cbiAgaWYgKG90aGVycy5sZW5ndGggPT09IDApIHsgcmV0dXJuIHt9OyB9XG4gIGNvbnN0IGludG8gPSBvdGhlcnMuc3BsaWNlKDAsIDEpWzBdO1xuXG4gIG90aGVycy5mb3JFYWNoKG90aGVyID0+IG1lcmdlT25lKGludG8sIG90aGVyKSk7XG4gIHJldHVybiBpbnRvO1xufVxuXG4vKipcbiAqIFNwbGl0cyB0aGUgZ2l2ZW4gb2JqZWN0IGludG8gdHdvLCBzdWNoIHRoYXQ6XG4gKlxuICogMS4gVGhlIHNpemUgb2YgdGhlIGZpcnN0IG9iamVjdCAoYWZ0ZXIgc3RyaW5naWZpZWQgaW4gVVRGLTgpIGlzIGxlc3MgdGhhbiBvciBlcXVhbCB0byB0aGUgcHJvdmlkZWQgc2l6ZSBsaW1pdC5cbiAqIDIuIE1lcmdpbmcgdGhlIHR3byBvYmplY3RzIHJlc3VsdHMgaW4gdGhlIG9yaWdpbmFsIG9uZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNwbGl0QnlTaXplKGRhdGE6IGFueSwgbWF4U2l6ZUJ5dGVzOiBudW1iZXIpOiBbYW55LCBhbnldIHtcbiAgaWYgKG1heFNpemVCeXRlcyA8IDIpIHtcbiAgICAvLyBJdCdzIGltcG9zc2libGUgdG8gZml0IGFueXRoaW5nIGluIHRoZSBmaXJzdCBvYmplY3RcbiAgICByZXR1cm4gW3VuZGVmaW5lZCwgZGF0YV07XG4gIH1cbiAgY29uc3QgZW50cmllcyA9IE9iamVjdC5lbnRyaWVzKGRhdGEpO1xuICByZXR1cm4gcmVjdXJzZSgwLCAwKTtcblxuICBmdW5jdGlvbiByZWN1cnNlKGluZGV4OiBudW1iZXIsIHJ1bm5pbmdUb3RhbFNpemU6IG51bWJlcik6IFthbnksIGFueV0ge1xuICAgIGlmIChpbmRleCA+PSBlbnRyaWVzLmxlbmd0aCkge1xuICAgICAgLy8gRXZlcnl0aGluZyBmaXRzIGluIHRoZSBmaXJzdCBvYmplY3RcbiAgICAgIHJldHVybiBbZGF0YSwgdW5kZWZpbmVkXTtcbiAgICB9XG5cbiAgICBjb25zdCBzaXplID0gcnVubmluZ1RvdGFsU2l6ZSArIGVudHJ5U2l6ZShlbnRyaWVzW2luZGV4XSk7XG4gICAgcmV0dXJuIChzaXplID4gbWF4U2l6ZUJ5dGVzKSA/IGN1dEF0KGluZGV4KSA6IHJlY3Vyc2UoaW5kZXggKyAxLCBzaXplKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGVudHJ5U2l6ZShlbnRyeTogW3N0cmluZywgdW5rbm93bl0pIHtcbiAgICByZXR1cm4gQnVmZmVyLmJ5dGVMZW5ndGgoSlNPTi5zdHJpbmdpZnkoT2JqZWN0LmZyb21FbnRyaWVzKFtlbnRyeV0pKSk7XG4gIH1cblxuICBmdW5jdGlvbiBjdXRBdChpbmRleDogbnVtYmVyKTogW2FueSwgYW55XSB7XG4gICAgcmV0dXJuIFtcbiAgICAgIE9iamVjdC5mcm9tRW50cmllcyhlbnRyaWVzLnNsaWNlKDAsIGluZGV4KSksXG4gICAgICBPYmplY3QuZnJvbUVudHJpZXMoZW50cmllcy5zbGljZShpbmRleCkpLFxuICAgIF07XG4gIH1cbn0iXX0=