UNPKG

@creditkarma/dynamic-config

Version:

Dynamic Config for Node.js backed by Consul and Vault

111 lines 3.71 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.resolveConfigPromises = exports.valuesForPromises = void 0; const ConfigUtils = require("./config"); const ConfigBuilder = require("./config-builder"); /** * Recursively traverses an object, looking for keys with Promised values and returns a Promise of * the object with all nested Promises resolved. */ async function valuesForPromises(promises) { return Promise.all(promises.map((next, index) => { return resolveAtIndex(next, index); })).then((values) => { return processValues(values); }); } exports.valuesForPromises = valuesForPromises; function processValues(values) { return values .sort((a, b) => { if (a[1] < b[1]) { return -1; } else { return 1; } }) .map((next) => { return next[0]; }); } function resolveAtIndex(promise, index) { return new Promise((resolve, reject) => { promise.then((val) => { return resolve([val, index]); }); }); } function appendUpdatesForObject(value, path, updates) { if (value instanceof Promise) { updates.push([path, value]); } else if (typeof value === 'object') { collectUnresolvedPromises(value, path, updates); } } async function handleUnresolved(unresolved, base) { const paths = unresolved.map((next) => next[0].join('.')); const promises = unresolved.map((next) => next[1]); const resolvedPromises = await Promise.all(promises.map((next) => { return next.then((val) => { const nested = collectUnresolvedPromises(val); if (nested.length > 0) { return handleUnresolved(nested, val); } else { return Promise.resolve(val); } }); })); const newObj = resolvedPromises.reduce((acc, next, currentIndex) => { return ConfigUtils.setValueForKey(paths[currentIndex], next, acc); }, base); return newObj; } function collectUnresolvedPromises(configValue, path = [], updates = []) { if (configValue.type === 'array') { for (let i = 0; i < configValue.items.length; i++) { const value = configValue.items[i]; const newPath = [...path, `${i}`]; appendUpdatesForObject(value, newPath, updates); } return updates; } else if (configValue.type === 'promise') { updates.push([ path, configValue.value.then((value) => { return ConfigBuilder.buildBaseConfigValue(configValue.source, value); }), ]); return updates; } else if (configValue.type === 'object' || configValue.type === 'root') { for (const key of Object.keys(configValue.properties)) { const value = configValue.properties[key]; const newPath = [...path, key]; appendUpdatesForObject(value, newPath, updates); } return updates; } else { return []; } } async function resolveConfigPromises(configValue) { if (configValue.type === 'promise') { return configValue.value.then((val) => { return resolveConfigPromises(ConfigBuilder.buildBaseConfigValue(configValue.source, val)); }); } else if (configValue.type === 'object' || configValue.type === 'root') { const unresolved = collectUnresolvedPromises(configValue); return handleUnresolved(unresolved, configValue); } else { return configValue; } } exports.resolveConfigPromises = resolveConfigPromises; //# sourceMappingURL=config-promises.js.map