/**
@license
 * @pnp/config-store v1.1.5-4 - pnp - provides a way to manage configuration within your application
 * MIT (https://github.com/pnp/pnpjs/blob/master/LICENSE)
 * Copyright (c) 2018 Microsoft
 * docs: https://pnp.github.io/pnpjs/
 * source: https:github.com/pnp/pnpjs
 * bugs: https://github.com/pnp/pnpjs/issues
 */
(function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@pnp/common')) :
    typeof define === 'function' && define.amd ? define(['exports', '@pnp/common'], factory) :
    (factory((global.pnp = global.pnp || {}, global.pnp['config-store'] = {}),global.pnp.common));
}(this, (function (exports,common) { 'use strict';

    /**
     * Class used to manage the current application settings
     *
     */
    var Settings = /** @class */ (function () {
        /**
         * Creates a new instance of the settings class
         *
         * @constructor
         */
        function Settings(_settings) {
            if (_settings === void 0) { _settings = new Map(); }
            this._settings = _settings;
        }
        /**
         * Adds a new single setting, or overwrites a previous setting with the same key
         *
         * @param {string} key The key used to store this setting
         * @param {string} value The setting value to store
         */
        Settings.prototype.add = function (key, value) {
            this._settings.set(key, value);
        };
        /**
         * Adds a JSON value to the collection as a string, you must use getJSON to rehydrate the object when read
         *
         * @param {string} key The key used to store this setting
         * @param {any} value The setting value to store
         */
        Settings.prototype.addJSON = function (key, value) {
            this._settings.set(key, common.jsS(value));
        };
        /**
         * Applies the supplied hash to the setting collection overwriting any existing value, or created new values
         *
         * @param {TypedHash<any>} hash The set of values to add
         */
        Settings.prototype.apply = function (hash) {
            var _this = this;
            return new Promise(function (resolve, reject) {
                try {
                    _this._settings = common.mergeMaps(_this._settings, common.objectToMap(hash));
                    resolve();
                }
                catch (e) {
                    reject(e);
                }
            });
        };
        /**
         * Loads configuration settings into the collection from the supplied provider and returns a Promise
         *
         * @param {IConfigurationProvider} provider The provider from which we will load the settings
         */
        Settings.prototype.load = function (provider) {
            var _this = this;
            return new Promise(function (resolve, reject) {
                provider.getConfiguration().then(function (value) {
                    _this._settings = common.mergeMaps(_this._settings, common.objectToMap(value));
                    resolve();
                }).catch(reject);
            });
        };
        /**
         * Gets a value from the configuration
         *
         * @param {string} key The key whose value we want to return. Returns null if the key does not exist
         * @return {string} string value from the configuration
         */
        Settings.prototype.get = function (key) {
            return this._settings.get(key);
        };
        /**
         * Gets a JSON value, rehydrating the stored string to the original object
         *
         * @param {string} key The key whose value we want to return. Returns null if the key does not exist
         * @return {any} object from the configuration
         */
        Settings.prototype.getJSON = function (key) {
            var o = this.get(key);
            if (o === undefined || o === null) {
                return o;
            }
            return JSON.parse(o);
        };
        return Settings;
    }());

    /**
     * A caching provider which can wrap other non-caching providers
     *
     */
    var CachingConfigurationProvider = /** @class */ (function () {
        /**
         * Creates a new caching configuration provider
         * @constructor
         * @param {IConfigurationProvider} wrappedProvider Provider which will be used to fetch the configuration
         * @param {string} cacheKey Key that will be used to store cached items to the cache
         * @param {IPnPClientStore} cacheStore OPTIONAL storage, which will be used to store cached settings.
         */
        function CachingConfigurationProvider(wrappedProvider, cacheKey, cacheStore) {
            this.wrappedProvider = wrappedProvider;
            this.cacheKey = cacheKey;
            this.wrappedProvider = wrappedProvider;
            this.store = (cacheStore) ? cacheStore : this.selectPnPCache();
        }
        /**
         * Gets the wrapped configuration providers
         *
         * @return {IConfigurationProvider} Wrapped configuration provider
         */
        CachingConfigurationProvider.prototype.getWrappedProvider = function () {
            return this.wrappedProvider;
        };
        /**
         * Loads the configuration values either from the cache or from the wrapped provider
         *
         * @return {Promise<TypedHash<string>>} Promise of loaded configuration values
         */
        CachingConfigurationProvider.prototype.getConfiguration = function () {
            var _this = this;
            // Cache not available, pass control to the wrapped provider
            if ((!this.store) || (!this.store.enabled)) {
                return this.wrappedProvider.getConfiguration();
            }
            return this.store.getOrPut(this.cacheKey, function () {
                return _this.wrappedProvider.getConfiguration().then(function (providedConfig) {
                    _this.store.put(_this.cacheKey, providedConfig);
                    return providedConfig;
                });
            });
        };
        CachingConfigurationProvider.prototype.selectPnPCache = function () {
            var pnpCache = new common.PnPClientStorage();
            if ((pnpCache.local) && (pnpCache.local.enabled)) {
                return pnpCache.local;
            }
            if ((pnpCache.session) && (pnpCache.session.enabled)) {
                return pnpCache.session;
            }
            throw new Error("Cannot create a caching configuration provider since cache is not available.");
        };
        return CachingConfigurationProvider;
    }());

    /**
     * A configuration provider which loads configuration values from a SharePoint list
     *
     */
    var SPListConfigurationProvider = /** @class */ (function () {
        /**
         * Creates a new SharePoint list based configuration provider
         * @constructor
         * @param {string} webUrl Url of the SharePoint site, where the configuration list is located
         * @param {string} listTitle Title of the SharePoint list, which contains the configuration settings (optional, default: "config")
         * @param {string} keyFieldName The name of the field in the list to use as the setting key (optional, default: "Title")
         * @param {string} valueFieldName The name of the field in the list to use as the setting value (optional, default: "Value")
         */
        function SPListConfigurationProvider(web, listTitle, keyFieldName, valueFieldName) {
            if (listTitle === void 0) { listTitle = "config"; }
            if (keyFieldName === void 0) { keyFieldName = "Title"; }
            if (valueFieldName === void 0) { valueFieldName = "Value"; }
            this.web = web;
            this.listTitle = listTitle;
            this.keyFieldName = keyFieldName;
            this.valueFieldName = valueFieldName;
        }
        /**
         * Loads the configuration values from the SharePoint list
         *
         * @return {Promise<TypedHash<string>>} Promise of loaded configuration values
         */
        SPListConfigurationProvider.prototype.getConfiguration = function () {
            var _this = this;
            return this.web.lists.getByTitle(this.listTitle).items.select(this.keyFieldName, this.valueFieldName).get()
                .then(function (data) { return data.reduce(function (c, item) {
                c[item[_this.keyFieldName]] = item[_this.valueFieldName];
                return c;
            }, {}); });
        };
        /**
         * Wraps the current provider in a cache enabled provider
         *
         * @return {CachingConfigurationProvider} Caching providers which wraps the current provider
         */
        SPListConfigurationProvider.prototype.asCaching = function (cacheKey) {
            if (cacheKey === void 0) { cacheKey = "pnp_configcache_splist_" + this.web.toUrl() + "+" + this.listTitle; }
            return new CachingConfigurationProvider(this, cacheKey);
        };
        return SPListConfigurationProvider;
    }());

    exports.Settings = Settings;
    exports.CachingConfigurationProvider = CachingConfigurationProvider;
    exports.SPListConfigurationProvider = SPListConfigurationProvider;

    Object.defineProperty(exports, '__esModule', { value: true });

})));
//# sourceMappingURL=config-store.es5.umd.js.map
