UNPKG

ibm-appconfiguration-js-client-sdk

Version:
209 lines (208 loc) 9.55 kB
"use strict"; /** * Copyright 2022 IBM Corp. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); var Constants = __importStar(require("../utils/constants")); var metering_1 = __importDefault(require("../utils/metering")); var Cache_1 = require("./Cache"); var PropertySegmentRule_1 = __importDefault(require("./PropertySegmentRule")); var logger_1 = require("../utils/logger"); var logger = new logger_1.Logger(Constants.APP_CONFIGURATION); var Property = /** @class */ (function () { function Property(_a) { var name = _a.name, property_id = _a.property_id, type = _a.type, _b = _a.format, format = _b === void 0 ? undefined : _b, value = _a.value, segment_rules = _a.segment_rules; this.name = name; this.property_id = property_id; this.type = type; this.format = format; // will be undefined for boolean & numeric datatypes this.value = value; this.segment_rules = []; for (var _i = 0, segment_rules_1 = segment_rules; _i < segment_rules_1.length; _i++) { var element = segment_rules_1[_i]; this.segment_rules.push(new PropertySegmentRule_1.default(element)); } } /** * Get the Property name. * * @return {*} {string} The Property name. * @memberof Property */ Property.prototype.getPropertyName = function () { return this.name; }; /** * Get the Property id. * * @return {*} {string} The Property Id. * @memberof Property */ Property.prototype.getPropertyId = function () { return this.property_id; }; /** * Get the Property data type. * * @return {*} {string} string named BOOLEAN/STRING/NUMERIC. * @memberof Property */ Property.prototype.getPropertyDataType = function () { return this.type; }; /** * Get the Property data format. * Applicable only for STRING datatype property. * * @return {*} {(string | undefined)} string named TEXT/JSON/YAML. * @memberof Property */ Property.prototype.getPropertyDataFormat = function () { // Format will be `undefined` for Boolean & Numeric properties // If the Format is null or undefined for a String type, we default it to TEXT if (!(this.format) && this.type === 'STRING') { this.format = 'TEXT'; } return this.format; }; /** * Get the evaluated value of the property. * * @param {string} entityId - Id of the Entity. * This will be a string identifier related to the Entity against which the property is evaluated. * For example, an entity might be an instance of an app that runs on a mobile device, a microservice that runs on the cloud, or a component of infrastructure that runs that microservice. * For any entity to interact with App Configuration, it must provide a unique entity ID. * * @param {{ [x: string]: any; }} entityAttributes - A JSON object consisting of the attribute name and their values that defines the specified entity. * This is an optional parameter if the property is not configured with any targeting definition. If the targeting is configured, then entityAttributes should be provided for the rule evaluation. * An attribute is a parameter that is used to define a segment. The SDK uses the attribute values to determine if the * specified entity satisfies the targeting rules, and returns the appropriate property value. * * @return {*} {*} Returns the default property value or its overridden value based on the evaluation. * The data type of returned value matches that of property. * @memberof Property */ Property.prototype.getCurrentValue = function (entityId, entityAttributes) { if (entityAttributes === void 0) { entityAttributes = {}; } if (!entityId) { logger.log(''.concat('Property evaluation: ', Constants.INVALID_ENTITY_ID, ' getCurrentValue')); return null; } return this.propertyEvaluation(entityId, entityAttributes); }; Property.prototype.propertyEvaluation = function (entityId, entityAttributes) { var evaluationResult = { evaluated_segment_id: Constants.DEFAULT_SEGMENT_ID, value: null, }; try { // check whether the property is configured with any targeting definition and then check whether the user has passed an valid entityAttributes JSON before we evaluate if (this.segment_rules.length > 0 && Object.keys(entityAttributes).length > 0) { var rulesMap = this.parseRules(this.segment_rules); evaluationResult = this.evaluateRules(rulesMap, entityId, entityAttributes); return evaluationResult.value; } return this.value; } finally { metering_1.default.getInstance().addMetering(entityId, evaluationResult.evaluated_segment_id, null, this.property_id); } }; Property.prototype.parseRules = function (segmentRules) { var rulesMap = {}; segmentRules.forEach(function (rules) { rulesMap[rules.order] = rules; }); return rulesMap; }; Property.prototype.evaluateRules = function (rulesMap, _entityId, entityAttributes) { var resultDict = { evaluated_segment_id: Constants.DEFAULT_SEGMENT_ID, value: null, }; try { // for each rules in the targeting for (var index = 1; index <= Object.keys(rulesMap).length; index += 1) { var segmentRule = rulesMap[index]; if (segmentRule.rules.length > 0) { for (var _i = 0, _a = segmentRule.rules; _i < _a.length; _i++) { var level = _a[_i]; var segments = level.segments; if (segments.length > 0) { // for each segment in a rule for (var _b = 0, segments_1 = segments; _b < segments_1.length; _b++) { var innerLevel = segments_1[_b]; var segmentId = innerLevel; // check whether the entityAttributes satifies all the rules of that segment if (this.evaluateSegment(segmentId, entityAttributes)) { resultDict.evaluated_segment_id = segmentId; { if (segmentRule.value === Constants.DEFAULT_PROPERTY_VALUE) { resultDict.value = this.value; } else { resultDict.value = segmentRule.value; } } return resultDict; } } } } } } } catch (e) { console.error(''.concat(Constants.APP_CONFIGURATION, 'PropertyRuleEvaluation', e.message)); } resultDict.value = this.value; return resultDict; }; Property.prototype.evaluateSegment = function (segmentId, entityAttributes) { var segment = (0, Cache_1.getCacheInstance)().segments; if (Object.prototype.hasOwnProperty.call(segment, segmentId)) { return segment[segmentId].evaluateRule(entityAttributes); } return false; }; return Property; }()); exports.default = Property;